1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2009-2017 Alexander Motin <mav@FreeBSD.org>
5 * Copyright (c) 1997-2009 by Matthew Jacob
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice immediately at the beginning of the file, without modification,
13 * this list of conditions, and the following disclaimer.
14 * 2. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
32 */
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD: stable/12/sys/dev/isp/isp_freebsd.c 368426 2020-12-08 00:58:02Z mav $");
35
36 #include <dev/isp/isp_freebsd.h>
37 #include <sys/unistd.h>
38 #include <sys/kthread.h>
39 #include <sys/conf.h>
40 #include <sys/module.h>
41 #include <sys/ioccom.h>
42 #include <dev/isp/isp_ioctl.h>
43 #include <sys/devicestat.h>
44 #include <cam/cam_periph.h>
45 #include <cam/cam_xpt_periph.h>
46
47 MODULE_VERSION(isp, 1);
48 MODULE_DEPEND(isp, cam, 1, 1, 1);
49 int isp_announced = 0;
50 int isp_loop_down_limit = 60; /* default loop down limit */
51 int isp_quickboot_time = 7; /* don't wait more than N secs for loop up */
52 int isp_gone_device_time = 30; /* grace time before reporting device lost */
53 static const char prom3[] = "Chan %d [%u] PortID 0x%06x Departed because of %s";
54
55 static void isp_freeze_loopdown(ispsoftc_t *, int);
56 static void isp_loop_changed(ispsoftc_t *isp, int chan);
57 static d_ioctl_t ispioctl;
58 static void isp_cam_async(void *, uint32_t, struct cam_path *, void *);
59 static void isp_poll(struct cam_sim *);
60 static timeout_t isp_watchdog;
61 static timeout_t isp_gdt;
62 static task_fn_t isp_gdt_task;
63 static void isp_kthread(void *);
64 static void isp_action(struct cam_sim *, union ccb *);
65 static int isp_timer_count;
66 static void isp_timer(void *);
67
68 static struct cdevsw isp_cdevsw = {
69 .d_version = D_VERSION,
70 .d_ioctl = ispioctl,
71 .d_name = "isp",
72 };
73
74 static int
isp_role_sysctl(SYSCTL_HANDLER_ARGS)75 isp_role_sysctl(SYSCTL_HANDLER_ARGS)
76 {
77 ispsoftc_t *isp = (ispsoftc_t *)arg1;
78 int chan = arg2;
79 int error, old, value;
80
81 value = FCPARAM(isp, chan)->role;
82
83 error = sysctl_handle_int(oidp, &value, 0, req);
84 if ((error != 0) || (req->newptr == NULL))
85 return (error);
86
87 if (value < ISP_ROLE_NONE || value > ISP_ROLE_BOTH)
88 return (EINVAL);
89
90 ISP_LOCK(isp);
91 old = FCPARAM(isp, chan)->role;
92
93 /* We don't allow target mode switch from here. */
94 value = (old & ISP_ROLE_TARGET) | (value & ISP_ROLE_INITIATOR);
95
96 /* If nothing has changed -- we are done. */
97 if (value == old) {
98 ISP_UNLOCK(isp);
99 return (0);
100 }
101
102 /* Actually change the role. */
103 error = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, value);
104 ISP_UNLOCK(isp);
105 return (error);
106 }
107
108 static int
isp_attach_chan(ispsoftc_t * isp,struct cam_devq * devq,int chan)109 isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
110 {
111 struct ccb_setasync csa;
112 struct cam_sim *sim;
113 struct cam_path *path;
114 #ifdef ISP_TARGET_MODE
115 int i;
116 #endif
117
118 sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
119 device_get_unit(isp->isp_dev), &isp->isp_lock,
120 isp->isp_maxcmds, isp->isp_maxcmds, devq);
121 if (sim == NULL)
122 return (ENOMEM);
123
124 if (xpt_bus_register(sim, isp->isp_dev, chan) != CAM_SUCCESS) {
125 cam_sim_free(sim, FALSE);
126 return (EIO);
127 }
128 if (xpt_create_path(&path, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
129 xpt_bus_deregister(cam_sim_path(sim));
130 cam_sim_free(sim, FALSE);
131 return (ENXIO);
132 }
133 xpt_setup_ccb(&csa.ccb_h, path, 5);
134 csa.ccb_h.func_code = XPT_SASYNC_CB;
135 csa.event_enable = AC_LOST_DEVICE;
136 csa.callback = isp_cam_async;
137 csa.callback_arg = sim;
138
139 ISP_LOCK(isp);
140 xpt_action((union ccb *)&csa);
141 ISP_UNLOCK(isp);
142
143 if (IS_SCSI(isp)) {
144 struct isp_spi *spi = ISP_SPI_PC(isp, chan);
145 spi->sim = sim;
146 spi->path = path;
147 #ifdef ISP_TARGET_MODE
148 TAILQ_INIT(&spi->waitq);
149 STAILQ_INIT(&spi->ntfree);
150 for (i = 0; i < ATPDPSIZE; i++)
151 STAILQ_INSERT_TAIL(&spi->ntfree, &spi->ntpool[i], next);
152 LIST_INIT(&spi->atfree);
153 for (i = ATPDPSIZE-1; i >= 0; i--)
154 LIST_INSERT_HEAD(&spi->atfree, &spi->atpool[i], next);
155 for (i = 0; i < ATPDPHASHSIZE; i++)
156 LIST_INIT(&spi->atused[i]);
157 #endif
158 } else {
159 fcparam *fcp = FCPARAM(isp, chan);
160 struct isp_fc *fc = ISP_FC_PC(isp, chan);
161 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(isp->isp_osinfo.dev);
162 struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev);
163 char name[16];
164
165 fc->sim = sim;
166 fc->path = path;
167 fc->isp = isp;
168 fc->ready = 1;
169 fcp->isp_use_gft_id = 1;
170 fcp->isp_use_gff_id = 1;
171
172 callout_init_mtx(&fc->gdt, &isp->isp_lock, 0);
173 TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc);
174 #ifdef ISP_TARGET_MODE
175 TAILQ_INIT(&fc->waitq);
176 STAILQ_INIT(&fc->ntfree);
177 for (i = 0; i < ATPDPSIZE; i++)
178 STAILQ_INSERT_TAIL(&fc->ntfree, &fc->ntpool[i], next);
179 LIST_INIT(&fc->atfree);
180 for (i = ATPDPSIZE-1; i >= 0; i--)
181 LIST_INSERT_HEAD(&fc->atfree, &fc->atpool[i], next);
182 for (i = 0; i < ATPDPHASHSIZE; i++)
183 LIST_INIT(&fc->atused[i]);
184 #endif
185 isp_loop_changed(isp, chan);
186 if (kproc_create(isp_kthread, fc, &fc->kproc, 0, 0,
187 "%s_%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
188 xpt_free_path(fc->path);
189 ISP_LOCK(isp);
190 xpt_bus_deregister(cam_sim_path(fc->sim));
191 ISP_UNLOCK(isp);
192 cam_sim_free(fc->sim, FALSE);
193 return (ENOMEM);
194 }
195 fc->num_threads += 1;
196 if (chan > 0) {
197 snprintf(name, sizeof(name), "chan%d", chan);
198 tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree),
199 OID_AUTO, name, CTLFLAG_RW, 0, "Virtual channel");
200 }
201 SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
202 "wwnn", CTLFLAG_RD, &fcp->isp_wwnn,
203 "World Wide Node Name");
204 SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
205 "wwpn", CTLFLAG_RD, &fcp->isp_wwpn,
206 "World Wide Port Name");
207 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
208 "loop_down_limit", CTLFLAG_RW, &fc->loop_down_limit, 0,
209 "Loop Down Limit");
210 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
211 "gone_device_time", CTLFLAG_RW, &fc->gone_device_time, 0,
212 "Gone Device Time");
213 #if defined(ISP_TARGET_MODE) && defined(DEBUG)
214 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
215 "inject_lost_data_frame", CTLFLAG_RW, &fc->inject_lost_data_frame, 0,
216 "Cause a Lost Frame on a Read");
217 #endif
218 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
219 "role", CTLTYPE_INT | CTLFLAG_RW, isp, chan,
220 isp_role_sysctl, "I", "Current role");
221 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
222 "speed", CTLFLAG_RD, &fcp->isp_gbspeed, 0,
223 "Connection speed in gigabits");
224 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
225 "linkstate", CTLFLAG_RD, &fcp->isp_linkstate, 0,
226 "Link state");
227 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
228 "fwstate", CTLFLAG_RD, &fcp->isp_fwstate, 0,
229 "Firmware state");
230 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
231 "loopstate", CTLFLAG_RD, &fcp->isp_loopstate, 0,
232 "Loop state");
233 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
234 "topo", CTLFLAG_RD, &fcp->isp_topo, 0,
235 "Connection topology");
236 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
237 "use_gft_id", CTLFLAG_RWTUN, &fcp->isp_use_gft_id, 0,
238 "Use GFT_ID during fabric scan");
239 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
240 "use_gff_id", CTLFLAG_RWTUN, &fcp->isp_use_gff_id, 0,
241 "Use GFF_ID during fabric scan");
242 }
243 return (0);
244 }
245
246 static void
isp_detach_chan(ispsoftc_t * isp,int chan)247 isp_detach_chan(ispsoftc_t *isp, int chan)
248 {
249 struct cam_sim *sim;
250 struct cam_path *path;
251 struct ccb_setasync csa;
252 int *num_threads;
253
254 ISP_GET_PC(isp, chan, sim, sim);
255 ISP_GET_PC(isp, chan, path, path);
256 ISP_GET_PC_ADDR(isp, chan, num_threads, num_threads);
257
258 xpt_setup_ccb(&csa.ccb_h, path, 5);
259 csa.ccb_h.func_code = XPT_SASYNC_CB;
260 csa.event_enable = 0;
261 csa.callback = isp_cam_async;
262 csa.callback_arg = sim;
263 xpt_action((union ccb *)&csa);
264 xpt_free_path(path);
265 xpt_bus_deregister(cam_sim_path(sim));
266 cam_sim_free(sim, FALSE);
267
268 /* Wait for the channel's spawned threads to exit. */
269 wakeup(isp->isp_osinfo.pc.ptr);
270 while (*num_threads != 0)
271 mtx_sleep(isp, &isp->isp_lock, PRIBIO, "isp_reap", 100);
272 }
273
274 int
isp_attach(ispsoftc_t * isp)275 isp_attach(ispsoftc_t *isp)
276 {
277 const char *nu = device_get_nameunit(isp->isp_osinfo.dev);
278 int du = device_get_unit(isp->isp_dev);
279 int chan;
280
281 /*
282 * Create the device queue for our SIM(s).
283 */
284 isp->isp_osinfo.devq = cam_simq_alloc(isp->isp_maxcmds);
285 if (isp->isp_osinfo.devq == NULL) {
286 return (EIO);
287 }
288
289 for (chan = 0; chan < isp->isp_nchan; chan++) {
290 if (isp_attach_chan(isp, isp->isp_osinfo.devq, chan)) {
291 goto unwind;
292 }
293 }
294
295 callout_init_mtx(&isp->isp_osinfo.tmo, &isp->isp_lock, 0);
296 isp_timer_count = hz >> 2;
297 callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp);
298
299 isp->isp_osinfo.cdev = make_dev(&isp_cdevsw, du, UID_ROOT, GID_OPERATOR, 0600, "%s", nu);
300 if (isp->isp_osinfo.cdev) {
301 isp->isp_osinfo.cdev->si_drv1 = isp;
302 }
303 return (0);
304
305 unwind:
306 while (--chan >= 0) {
307 struct cam_sim *sim;
308 struct cam_path *path;
309
310 ISP_GET_PC(isp, chan, sim, sim);
311 ISP_GET_PC(isp, chan, path, path);
312 xpt_free_path(path);
313 xpt_bus_deregister(cam_sim_path(sim));
314 cam_sim_free(sim, FALSE);
315 }
316 cam_simq_free(isp->isp_osinfo.devq);
317 isp->isp_osinfo.devq = NULL;
318 return (-1);
319 }
320
321 int
isp_detach(ispsoftc_t * isp)322 isp_detach(ispsoftc_t *isp)
323 {
324 int chan;
325
326 if (isp->isp_osinfo.cdev) {
327 destroy_dev(isp->isp_osinfo.cdev);
328 isp->isp_osinfo.cdev = NULL;
329 }
330 ISP_LOCK(isp);
331 /* Tell spawned threads that we're exiting. */
332 isp->isp_osinfo.is_exiting = 1;
333 for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1)
334 isp_detach_chan(isp, chan);
335 ISP_UNLOCK(isp);
336 callout_drain(&isp->isp_osinfo.tmo);
337 cam_simq_free(isp->isp_osinfo.devq);
338 return (0);
339 }
340
341 static void
isp_freeze_loopdown(ispsoftc_t * isp,int chan)342 isp_freeze_loopdown(ispsoftc_t *isp, int chan)
343 {
344 struct isp_fc *fc = ISP_FC_PC(isp, chan);
345
346 if (fc->sim == NULL)
347 return;
348 if (fc->simqfrozen == 0) {
349 isp_prt(isp, ISP_LOGDEBUG0,
350 "Chan %d Freeze simq (loopdown)", chan);
351 fc->simqfrozen = SIMQFRZ_LOOPDOWN;
352 xpt_hold_boot();
353 xpt_freeze_simq(fc->sim, 1);
354 } else {
355 isp_prt(isp, ISP_LOGDEBUG0,
356 "Chan %d Mark simq frozen (loopdown)", chan);
357 fc->simqfrozen |= SIMQFRZ_LOOPDOWN;
358 }
359 }
360
361 static void
isp_unfreeze_loopdown(ispsoftc_t * isp,int chan)362 isp_unfreeze_loopdown(ispsoftc_t *isp, int chan)
363 {
364 struct isp_fc *fc = ISP_FC_PC(isp, chan);
365
366 if (fc->sim == NULL)
367 return;
368 int wasfrozen = fc->simqfrozen & SIMQFRZ_LOOPDOWN;
369 fc->simqfrozen &= ~SIMQFRZ_LOOPDOWN;
370 if (wasfrozen && fc->simqfrozen == 0) {
371 isp_prt(isp, ISP_LOGDEBUG0,
372 "Chan %d Release simq", chan);
373 xpt_release_simq(fc->sim, 1);
374 xpt_release_boot();
375 }
376 }
377
378 static int
ispioctl(struct cdev * dev,u_long c,caddr_t addr,int flags,struct thread * td)379 ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
380 {
381 ispsoftc_t *isp;
382 int nr, chan, retval = ENOTTY;
383
384 isp = dev->si_drv1;
385
386 switch (c) {
387 case ISP_SDBLEV:
388 {
389 int olddblev = isp->isp_dblev;
390 isp->isp_dblev = *(int *)addr;
391 *(int *)addr = olddblev;
392 retval = 0;
393 break;
394 }
395 case ISP_GETROLE:
396 chan = *(int *)addr;
397 if (chan < 0 || chan >= isp->isp_nchan) {
398 retval = -ENXIO;
399 break;
400 }
401 if (IS_FC(isp)) {
402 *(int *)addr = FCPARAM(isp, chan)->role;
403 } else {
404 *(int *)addr = ISP_ROLE_INITIATOR;
405 }
406 retval = 0;
407 break;
408 case ISP_SETROLE:
409 if (IS_SCSI(isp))
410 break;
411 nr = *(int *)addr;
412 chan = nr >> 8;
413 if (chan < 0 || chan >= isp->isp_nchan) {
414 retval = -ENXIO;
415 break;
416 }
417 nr &= 0xff;
418 if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
419 retval = EINVAL;
420 break;
421 }
422 ISP_LOCK(isp);
423 *(int *)addr = FCPARAM(isp, chan)->role;
424 retval = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, nr);
425 ISP_UNLOCK(isp);
426 retval = 0;
427 break;
428
429 case ISP_RESETHBA:
430 ISP_LOCK(isp);
431 isp_reinit(isp, 0);
432 ISP_UNLOCK(isp);
433 retval = 0;
434 break;
435
436 case ISP_RESCAN:
437 if (IS_FC(isp)) {
438 chan = *(intptr_t *)addr;
439 if (chan < 0 || chan >= isp->isp_nchan) {
440 retval = -ENXIO;
441 break;
442 }
443 ISP_LOCK(isp);
444 if (isp_fc_runstate(isp, chan, 5 * 1000000) != LOOP_READY) {
445 retval = EIO;
446 } else {
447 retval = 0;
448 }
449 ISP_UNLOCK(isp);
450 }
451 break;
452
453 case ISP_FC_LIP:
454 if (IS_FC(isp)) {
455 chan = *(intptr_t *)addr;
456 if (chan < 0 || chan >= isp->isp_nchan) {
457 retval = -ENXIO;
458 break;
459 }
460 ISP_LOCK(isp);
461 if (isp_control(isp, ISPCTL_SEND_LIP, chan)) {
462 retval = EIO;
463 } else {
464 retval = 0;
465 }
466 ISP_UNLOCK(isp);
467 }
468 break;
469 case ISP_FC_GETDINFO:
470 {
471 struct isp_fc_device *ifc = (struct isp_fc_device *) addr;
472 fcportdb_t *lp;
473
474 if (IS_SCSI(isp)) {
475 break;
476 }
477 if (ifc->loopid >= MAX_FC_TARG) {
478 retval = EINVAL;
479 break;
480 }
481 lp = &FCPARAM(isp, ifc->chan)->portdb[ifc->loopid];
482 if (lp->state != FC_PORTDB_STATE_NIL) {
483 ifc->role = (lp->prli_word3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
484 ifc->loopid = lp->handle;
485 ifc->portid = lp->portid;
486 ifc->node_wwn = lp->node_wwn;
487 ifc->port_wwn = lp->port_wwn;
488 retval = 0;
489 } else {
490 retval = ENODEV;
491 }
492 break;
493 }
494 case ISP_FC_GETHINFO:
495 {
496 struct isp_hba_device *hba = (struct isp_hba_device *) addr;
497 int chan = hba->fc_channel;
498
499 if (chan < 0 || chan >= isp->isp_nchan) {
500 retval = ENXIO;
501 break;
502 }
503 hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev);
504 hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev);
505 hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev);
506 hba->fc_nchannels = isp->isp_nchan;
507 if (IS_FC(isp)) {
508 hba->fc_nports = MAX_FC_TARG;
509 hba->fc_speed = FCPARAM(isp, hba->fc_channel)->isp_gbspeed;
510 hba->fc_topology = FCPARAM(isp, chan)->isp_topo + 1;
511 hba->fc_loopid = FCPARAM(isp, chan)->isp_loopid;
512 hba->nvram_node_wwn = FCPARAM(isp, chan)->isp_wwnn_nvram;
513 hba->nvram_port_wwn = FCPARAM(isp, chan)->isp_wwpn_nvram;
514 hba->active_node_wwn = FCPARAM(isp, chan)->isp_wwnn;
515 hba->active_port_wwn = FCPARAM(isp, chan)->isp_wwpn;
516 } else {
517 hba->fc_nports = MAX_TARGETS;
518 hba->fc_speed = 0;
519 hba->fc_topology = 0;
520 hba->nvram_node_wwn = 0ull;
521 hba->nvram_port_wwn = 0ull;
522 hba->active_node_wwn = 0ull;
523 hba->active_port_wwn = 0ull;
524 }
525 retval = 0;
526 break;
527 }
528 case ISP_TSK_MGMT:
529 {
530 int needmarker;
531 struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
532 uint16_t nphdl;
533 mbreg_t mbs;
534
535 if (IS_SCSI(isp)) {
536 break;
537 }
538
539 chan = fct->chan;
540 if (chan < 0 || chan >= isp->isp_nchan) {
541 retval = -ENXIO;
542 break;
543 }
544
545 needmarker = retval = 0;
546 nphdl = fct->loopid;
547 ISP_LOCK(isp);
548 if (IS_24XX(isp)) {
549 void *reqp;
550 uint8_t resp[QENTRY_LEN];
551 isp24xx_tmf_t tmf;
552 isp24xx_statusreq_t sp;
553 fcparam *fcp = FCPARAM(isp, chan);
554 fcportdb_t *lp;
555 int i;
556
557 for (i = 0; i < MAX_FC_TARG; i++) {
558 lp = &fcp->portdb[i];
559 if (lp->handle == nphdl) {
560 break;
561 }
562 }
563 if (i == MAX_FC_TARG) {
564 retval = ENXIO;
565 ISP_UNLOCK(isp);
566 break;
567 }
568 ISP_MEMZERO(&tmf, sizeof(tmf));
569 tmf.tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
570 tmf.tmf_header.rqs_entry_count = 1;
571 tmf.tmf_nphdl = lp->handle;
572 tmf.tmf_delay = 2;
573 tmf.tmf_timeout = 4;
574 tmf.tmf_tidlo = lp->portid;
575 tmf.tmf_tidhi = lp->portid >> 16;
576 tmf.tmf_vpidx = ISP_GET_VPIDX(isp, chan);
577 tmf.tmf_lun[1] = fct->lun & 0xff;
578 if (fct->lun >= 256) {
579 tmf.tmf_lun[0] = 0x40 | (fct->lun >> 8);
580 }
581 switch (fct->action) {
582 case IPT_CLEAR_ACA:
583 tmf.tmf_flags = ISP24XX_TMF_CLEAR_ACA;
584 break;
585 case IPT_TARGET_RESET:
586 tmf.tmf_flags = ISP24XX_TMF_TARGET_RESET;
587 needmarker = 1;
588 break;
589 case IPT_LUN_RESET:
590 tmf.tmf_flags = ISP24XX_TMF_LUN_RESET;
591 needmarker = 1;
592 break;
593 case IPT_CLEAR_TASK_SET:
594 tmf.tmf_flags = ISP24XX_TMF_CLEAR_TASK_SET;
595 needmarker = 1;
596 break;
597 case IPT_ABORT_TASK_SET:
598 tmf.tmf_flags = ISP24XX_TMF_ABORT_TASK_SET;
599 needmarker = 1;
600 break;
601 default:
602 retval = EINVAL;
603 break;
604 }
605 if (retval) {
606 ISP_UNLOCK(isp);
607 break;
608 }
609
610 /* Prepare space for response in memory */
611 memset(resp, 0xff, sizeof(resp));
612 tmf.tmf_handle = isp_allocate_handle(isp, resp,
613 ISP_HANDLE_CTRL);
614 if (tmf.tmf_handle == 0) {
615 isp_prt(isp, ISP_LOGERR,
616 "%s: TMF of Chan %d out of handles",
617 __func__, chan);
618 ISP_UNLOCK(isp);
619 retval = ENOMEM;
620 break;
621 }
622
623 /* Send request and wait for response. */
624 reqp = isp_getrqentry(isp);
625 if (reqp == NULL) {
626 isp_prt(isp, ISP_LOGERR,
627 "%s: TMF of Chan %d out of rqent",
628 __func__, chan);
629 isp_destroy_handle(isp, tmf.tmf_handle);
630 ISP_UNLOCK(isp);
631 retval = EIO;
632 break;
633 }
634 isp_put_24xx_tmf(isp, &tmf, (isp24xx_tmf_t *)reqp);
635 if (isp->isp_dblev & ISP_LOGDEBUG1)
636 isp_print_bytes(isp, "IOCB TMF", QENTRY_LEN, reqp);
637 ISP_SYNC_REQUEST(isp);
638 if (msleep(resp, &isp->isp_lock, 0, "TMF", 5*hz) == EWOULDBLOCK) {
639 isp_prt(isp, ISP_LOGERR,
640 "%s: TMF of Chan %d timed out",
641 __func__, chan);
642 isp_destroy_handle(isp, tmf.tmf_handle);
643 ISP_UNLOCK(isp);
644 retval = EIO;
645 break;
646 }
647 if (isp->isp_dblev & ISP_LOGDEBUG1)
648 isp_print_bytes(isp, "IOCB TMF response", QENTRY_LEN, resp);
649 isp_get_24xx_response(isp, (isp24xx_statusreq_t *)resp, &sp);
650
651 if (sp.req_completion_status != 0)
652 retval = EIO;
653 else if (needmarker)
654 fcp->sendmarker = 1;
655 } else {
656 MBSINIT(&mbs, 0, MBLOGALL, 0);
657 if (ISP_CAP_2KLOGIN(isp) == 0) {
658 nphdl <<= 8;
659 }
660 switch (fct->action) {
661 case IPT_CLEAR_ACA:
662 mbs.param[0] = MBOX_CLEAR_ACA;
663 mbs.param[1] = nphdl;
664 mbs.param[2] = fct->lun;
665 break;
666 case IPT_TARGET_RESET:
667 mbs.param[0] = MBOX_TARGET_RESET;
668 mbs.param[1] = nphdl;
669 needmarker = 1;
670 break;
671 case IPT_LUN_RESET:
672 mbs.param[0] = MBOX_LUN_RESET;
673 mbs.param[1] = nphdl;
674 mbs.param[2] = fct->lun;
675 needmarker = 1;
676 break;
677 case IPT_CLEAR_TASK_SET:
678 mbs.param[0] = MBOX_CLEAR_TASK_SET;
679 mbs.param[1] = nphdl;
680 mbs.param[2] = fct->lun;
681 needmarker = 1;
682 break;
683 case IPT_ABORT_TASK_SET:
684 mbs.param[0] = MBOX_ABORT_TASK_SET;
685 mbs.param[1] = nphdl;
686 mbs.param[2] = fct->lun;
687 needmarker = 1;
688 break;
689 default:
690 retval = EINVAL;
691 break;
692 }
693 if (retval == 0) {
694 if (needmarker) {
695 FCPARAM(isp, chan)->sendmarker = 1;
696 }
697 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
698 if (retval) {
699 retval = EIO;
700 }
701 }
702 }
703 ISP_UNLOCK(isp);
704 break;
705 }
706 default:
707 break;
708 }
709 return (retval);
710 }
711
712 /*
713 * Local Inlines
714 */
715
716 static ISP_INLINE int isp_get_pcmd(ispsoftc_t *, union ccb *);
717 static ISP_INLINE void isp_free_pcmd(ispsoftc_t *, union ccb *);
718
719 static ISP_INLINE int
isp_get_pcmd(ispsoftc_t * isp,union ccb * ccb)720 isp_get_pcmd(ispsoftc_t *isp, union ccb *ccb)
721 {
722 ISP_PCMD(ccb) = isp->isp_osinfo.pcmd_free;
723 if (ISP_PCMD(ccb) == NULL) {
724 return (-1);
725 }
726 isp->isp_osinfo.pcmd_free = ((struct isp_pcmd *)ISP_PCMD(ccb))->next;
727 return (0);
728 }
729
730 static ISP_INLINE void
isp_free_pcmd(ispsoftc_t * isp,union ccb * ccb)731 isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb)
732 {
733 if (ISP_PCMD(ccb)) {
734 #ifdef ISP_TARGET_MODE
735 PISP_PCMD(ccb)->datalen = 0;
736 #endif
737 PISP_PCMD(ccb)->next = isp->isp_osinfo.pcmd_free;
738 isp->isp_osinfo.pcmd_free = ISP_PCMD(ccb);
739 ISP_PCMD(ccb) = NULL;
740 }
741 }
742
743 /*
744 * Put the target mode functions here, because some are inlines
745 */
746 #ifdef ISP_TARGET_MODE
747 static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
748 static atio_private_data_t *isp_get_atpd(ispsoftc_t *, int, uint32_t);
749 static atio_private_data_t *isp_find_atpd(ispsoftc_t *, int, uint32_t);
750 static void isp_put_atpd(ispsoftc_t *, int, atio_private_data_t *);
751 static inot_private_data_t *isp_get_ntpd(ispsoftc_t *, int);
752 static inot_private_data_t *isp_find_ntpd(ispsoftc_t *, int, uint32_t, uint32_t);
753 static void isp_put_ntpd(ispsoftc_t *, int, inot_private_data_t *);
754 static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
755 static void destroy_lun_state(ispsoftc_t *, int, tstate_t *);
756 static void isp_enable_lun(ispsoftc_t *, union ccb *);
757 static void isp_disable_lun(ispsoftc_t *, union ccb *);
758 static timeout_t isp_refire_putback_atio;
759 static timeout_t isp_refire_notify_ack;
760 static void isp_complete_ctio(union ccb *);
761 static void isp_target_putback_atio(union ccb *);
762 enum Start_Ctio_How { FROM_CAM, FROM_TIMER, FROM_SRR, FROM_CTIO_DONE };
763 static void isp_target_start_ctio(ispsoftc_t *, union ccb *, enum Start_Ctio_How);
764 static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
765 static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
766 static void isp_handle_platform_ctio(ispsoftc_t *, void *);
767 static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *, uint32_t rsp);
768 static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
769 static void isp_target_mark_aborted_early(ispsoftc_t *, int chan, tstate_t *, uint32_t);
770
771 static ISP_INLINE tstate_t *
get_lun_statep(ispsoftc_t * isp,int bus,lun_id_t lun)772 get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
773 {
774 tstate_t *tptr = NULL;
775 struct tslist *lhp;
776
777 if (bus < isp->isp_nchan) {
778 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
779 SLIST_FOREACH(tptr, lhp, next) {
780 if (tptr->ts_lun == lun)
781 return (tptr);
782 }
783 }
784 return (NULL);
785 }
786
787 static int
isp_atio_restart(ispsoftc_t * isp,int bus,tstate_t * tptr)788 isp_atio_restart(ispsoftc_t *isp, int bus, tstate_t *tptr)
789 {
790 inot_private_data_t *ntp;
791 struct ntpdlist rq;
792
793 if (STAILQ_EMPTY(&tptr->restart_queue))
794 return (0);
795 STAILQ_INIT(&rq);
796 STAILQ_CONCAT(&rq, &tptr->restart_queue);
797 while ((ntp = STAILQ_FIRST(&rq)) != NULL) {
798 STAILQ_REMOVE_HEAD(&rq, next);
799 if (IS_24XX(isp)) {
800 isp_prt(isp, ISP_LOGTDEBUG0,
801 "%s: restarting resrc deprived %x", __func__,
802 ((at7_entry_t *)ntp->data)->at_rxid);
803 isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->data);
804 } else {
805 isp_prt(isp, ISP_LOGTDEBUG0,
806 "%s: restarting resrc deprived %x", __func__,
807 ((at2_entry_t *)ntp->data)->at_rxid);
808 isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->data);
809 }
810 isp_put_ntpd(isp, bus, ntp);
811 if (!STAILQ_EMPTY(&tptr->restart_queue))
812 break;
813 }
814 if (!STAILQ_EMPTY(&rq)) {
815 STAILQ_CONCAT(&rq, &tptr->restart_queue);
816 STAILQ_CONCAT(&tptr->restart_queue, &rq);
817 }
818 return (!STAILQ_EMPTY(&tptr->restart_queue));
819 }
820
821 static void
isp_tmcmd_restart(ispsoftc_t * isp)822 isp_tmcmd_restart(ispsoftc_t *isp)
823 {
824 tstate_t *tptr;
825 union ccb *ccb;
826 struct tslist *lhp;
827 struct isp_ccbq *waitq;
828 int bus, i;
829
830 for (bus = 0; bus < isp->isp_nchan; bus++) {
831 for (i = 0; i < LUN_HASH_SIZE; i++) {
832 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
833 SLIST_FOREACH(tptr, lhp, next)
834 isp_atio_restart(isp, bus, tptr);
835 }
836
837 /*
838 * We only need to do this once per channel.
839 */
840 ISP_GET_PC_ADDR(isp, bus, waitq, waitq);
841 ccb = (union ccb *)TAILQ_FIRST(waitq);
842 if (ccb != NULL) {
843 TAILQ_REMOVE(waitq, &ccb->ccb_h, sim_links.tqe);
844 isp_target_start_ctio(isp, ccb, FROM_TIMER);
845 }
846 }
847 }
848
849 static atio_private_data_t *
isp_get_atpd(ispsoftc_t * isp,int chan,uint32_t tag)850 isp_get_atpd(ispsoftc_t *isp, int chan, uint32_t tag)
851 {
852 struct atpdlist *atfree;
853 struct atpdlist *atused;
854 atio_private_data_t *atp;
855
856 ISP_GET_PC_ADDR(isp, chan, atfree, atfree);
857 atp = LIST_FIRST(atfree);
858 if (atp) {
859 LIST_REMOVE(atp, next);
860 atp->tag = tag;
861 ISP_GET_PC(isp, chan, atused, atused);
862 LIST_INSERT_HEAD(&atused[ATPDPHASH(tag)], atp, next);
863 }
864 return (atp);
865 }
866
867 static atio_private_data_t *
isp_find_atpd(ispsoftc_t * isp,int chan,uint32_t tag)868 isp_find_atpd(ispsoftc_t *isp, int chan, uint32_t tag)
869 {
870 struct atpdlist *atused;
871 atio_private_data_t *atp;
872
873 ISP_GET_PC(isp, chan, atused, atused);
874 LIST_FOREACH(atp, &atused[ATPDPHASH(tag)], next) {
875 if (atp->tag == tag)
876 return (atp);
877 }
878 return (NULL);
879 }
880
881 static void
isp_put_atpd(ispsoftc_t * isp,int chan,atio_private_data_t * atp)882 isp_put_atpd(ispsoftc_t *isp, int chan, atio_private_data_t *atp)
883 {
884 struct atpdlist *atfree;
885
886 if (atp->ests) {
887 isp_put_ecmd(isp, atp->ests);
888 }
889 LIST_REMOVE(atp, next);
890 memset(atp, 0, sizeof (*atp));
891 ISP_GET_PC_ADDR(isp, chan, atfree, atfree);
892 LIST_INSERT_HEAD(atfree, atp, next);
893 }
894
895 static void
isp_dump_atpd(ispsoftc_t * isp,int chan)896 isp_dump_atpd(ispsoftc_t *isp, int chan)
897 {
898 atio_private_data_t *atp, *atpool;
899 const char *states[8] = { "Free", "ATIO", "CAM", "CTIO", "LAST_CTIO", "PDON", "?6", "7" };
900
901 ISP_GET_PC(isp, chan, atpool, atpool);
902 for (atp = atpool; atp < &atpool[ATPDPSIZE]; atp++) {
903 if (atp->state == ATPD_STATE_FREE)
904 continue;
905 isp_prt(isp, ISP_LOGALL, "Chan %d ATP [0x%x] origdlen %u bytes_xfrd %u lun %jx nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s",
906 chan, atp->tag, atp->orig_datalen, atp->bytes_xfered, (uintmax_t)atp->lun, atp->nphdl, atp->sid, atp->did, atp->oxid, states[atp->state & 0x7]);
907 }
908 }
909
910 static inot_private_data_t *
isp_get_ntpd(ispsoftc_t * isp,int chan)911 isp_get_ntpd(ispsoftc_t *isp, int chan)
912 {
913 struct ntpdlist *ntfree;
914 inot_private_data_t *ntp;
915
916 ISP_GET_PC_ADDR(isp, chan, ntfree, ntfree);
917 ntp = STAILQ_FIRST(ntfree);
918 if (ntp)
919 STAILQ_REMOVE_HEAD(ntfree, next);
920 return (ntp);
921 }
922
923 static inot_private_data_t *
isp_find_ntpd(ispsoftc_t * isp,int chan,uint32_t tag_id,uint32_t seq_id)924 isp_find_ntpd(ispsoftc_t *isp, int chan, uint32_t tag_id, uint32_t seq_id)
925 {
926 inot_private_data_t *ntp, *ntp2;
927
928 ISP_GET_PC(isp, chan, ntpool, ntp);
929 ISP_GET_PC_ADDR(isp, chan, ntpool[ATPDPSIZE], ntp2);
930 for (; ntp < ntp2; ntp++) {
931 if (ntp->tag_id == tag_id && ntp->seq_id == seq_id)
932 return (ntp);
933 }
934 return (NULL);
935 }
936
937 static void
isp_put_ntpd(ispsoftc_t * isp,int chan,inot_private_data_t * ntp)938 isp_put_ntpd(ispsoftc_t *isp, int chan, inot_private_data_t *ntp)
939 {
940 struct ntpdlist *ntfree;
941
942 ntp->tag_id = ntp->seq_id = 0;
943 ISP_GET_PC_ADDR(isp, chan, ntfree, ntfree);
944 STAILQ_INSERT_HEAD(ntfree, ntp, next);
945 }
946
947 static cam_status
create_lun_state(ispsoftc_t * isp,int bus,struct cam_path * path,tstate_t ** rslt)948 create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rslt)
949 {
950 lun_id_t lun;
951 struct tslist *lhp;
952 tstate_t *tptr;
953
954 lun = xpt_path_lun_id(path);
955 if (lun != CAM_LUN_WILDCARD) {
956 if (ISP_MAX_LUNS(isp) > 0 && lun >= ISP_MAX_LUNS(isp)) {
957 return (CAM_LUN_INVALID);
958 }
959 }
960 tptr = malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
961 if (tptr == NULL) {
962 return (CAM_RESRC_UNAVAIL);
963 }
964 tptr->ts_lun = lun;
965 SLIST_INIT(&tptr->atios);
966 SLIST_INIT(&tptr->inots);
967 STAILQ_INIT(&tptr->restart_queue);
968 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
969 SLIST_INSERT_HEAD(lhp, tptr, next);
970 *rslt = tptr;
971 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, path, "created tstate\n");
972 return (CAM_REQ_CMP);
973 }
974
975 static void
destroy_lun_state(ispsoftc_t * isp,int bus,tstate_t * tptr)976 destroy_lun_state(ispsoftc_t *isp, int bus, tstate_t *tptr)
977 {
978 union ccb *ccb;
979 struct tslist *lhp;
980 inot_private_data_t *ntp;
981
982 while ((ccb = (union ccb *)SLIST_FIRST(&tptr->atios)) != NULL) {
983 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
984 ccb->ccb_h.status = CAM_REQ_ABORTED;
985 xpt_done(ccb);
986 };
987 while ((ccb = (union ccb *)SLIST_FIRST(&tptr->inots)) != NULL) {
988 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
989 ccb->ccb_h.status = CAM_REQ_ABORTED;
990 xpt_done(ccb);
991 }
992 while ((ntp = STAILQ_FIRST(&tptr->restart_queue)) != NULL) {
993 isp_endcmd(isp, ntp->data, NIL_HANDLE, bus, SCSI_STATUS_BUSY, 0);
994 STAILQ_REMOVE_HEAD(&tptr->restart_queue, next);
995 isp_put_ntpd(isp, bus, ntp);
996 }
997 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(tptr->ts_lun)], lhp);
998 SLIST_REMOVE(lhp, tptr, tstate, next);
999 free(tptr, M_DEVBUF);
1000 }
1001
1002 static void
isp_enable_lun(ispsoftc_t * isp,union ccb * ccb)1003 isp_enable_lun(ispsoftc_t *isp, union ccb *ccb)
1004 {
1005 tstate_t *tptr;
1006 int bus;
1007 target_id_t target;
1008 lun_id_t lun;
1009
1010 if (!IS_FC(isp) || !ISP_CAP_TMODE(isp) || !ISP_CAP_SCCFW(isp)) {
1011 xpt_print(ccb->ccb_h.path, "Target mode is not supported\n");
1012 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1013 xpt_done(ccb);
1014 return;
1015 }
1016
1017 /*
1018 * We only support either target and lun both wildcard
1019 * or target and lun both non-wildcard.
1020 */
1021 bus = XS_CHANNEL(ccb);
1022 target = ccb->ccb_h.target_id;
1023 lun = ccb->ccb_h.target_lun;
1024 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path,
1025 "enabling lun %jx\n", (uintmax_t)lun);
1026 if ((target == CAM_TARGET_WILDCARD) != (lun == CAM_LUN_WILDCARD)) {
1027 ccb->ccb_h.status = CAM_LUN_INVALID;
1028 xpt_done(ccb);
1029 return;
1030 }
1031
1032 /* Create the state pointer. It should not already exist. */
1033 tptr = get_lun_statep(isp, bus, lun);
1034 if (tptr) {
1035 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
1036 xpt_done(ccb);
1037 return;
1038 }
1039 ccb->ccb_h.status = create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
1040 if (ccb->ccb_h.status != CAM_REQ_CMP) {
1041 xpt_done(ccb);
1042 return;
1043 }
1044
1045 ccb->ccb_h.status = CAM_REQ_CMP;
1046 xpt_done(ccb);
1047 }
1048
1049 static void
isp_disable_lun(ispsoftc_t * isp,union ccb * ccb)1050 isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
1051 {
1052 tstate_t *tptr = NULL;
1053 int bus;
1054 target_id_t target;
1055 lun_id_t lun;
1056
1057 bus = XS_CHANNEL(ccb);
1058 target = ccb->ccb_h.target_id;
1059 lun = ccb->ccb_h.target_lun;
1060 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path,
1061 "disabling lun %jx\n", (uintmax_t)lun);
1062 if ((target == CAM_TARGET_WILDCARD) != (lun == CAM_LUN_WILDCARD)) {
1063 ccb->ccb_h.status = CAM_LUN_INVALID;
1064 xpt_done(ccb);
1065 return;
1066 }
1067
1068 /* Find the state pointer. */
1069 if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) {
1070 ccb->ccb_h.status = CAM_PATH_INVALID;
1071 xpt_done(ccb);
1072 return;
1073 }
1074
1075 destroy_lun_state(isp, bus, tptr);
1076 ccb->ccb_h.status = CAM_REQ_CMP;
1077 xpt_done(ccb);
1078 }
1079
1080 static void
isp_target_start_ctio(ispsoftc_t * isp,union ccb * ccb,enum Start_Ctio_How how)1081 isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
1082 {
1083 int fctape, sendstatus, resid;
1084 fcparam *fcp;
1085 atio_private_data_t *atp;
1086 struct ccb_scsiio *cso;
1087 struct isp_ccbq *waitq;
1088 uint32_t dmaresult, handle, xfrlen, sense_length, tmp;
1089 uint8_t local[QENTRY_LEN];
1090
1091 isp_prt(isp, ISP_LOGTDEBUG0, "%s: ENTRY[0x%x] how %u xfrlen %u sendstatus %d sense_len %u", __func__, ccb->csio.tag_id, how, ccb->csio.dxfer_len,
1092 (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0, ((ccb->ccb_h.flags & CAM_SEND_SENSE)? ccb->csio.sense_len : 0));
1093
1094 ISP_GET_PC_ADDR(isp, XS_CHANNEL(ccb), waitq, waitq);
1095 switch (how) {
1096 case FROM_CAM:
1097 /*
1098 * Insert at the tail of the list, if any, waiting CTIO CCBs
1099 */
1100 TAILQ_INSERT_TAIL(waitq, &ccb->ccb_h, sim_links.tqe);
1101 break;
1102 case FROM_TIMER:
1103 case FROM_SRR:
1104 case FROM_CTIO_DONE:
1105 TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, sim_links.tqe);
1106 break;
1107 }
1108
1109 while ((ccb = (union ccb *) TAILQ_FIRST(waitq)) != NULL) {
1110 TAILQ_REMOVE(waitq, &ccb->ccb_h, sim_links.tqe);
1111
1112 cso = &ccb->csio;
1113 xfrlen = cso->dxfer_len;
1114 if (xfrlen == 0) {
1115 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) {
1116 ISP_PATH_PRT(isp, ISP_LOGERR, ccb->ccb_h.path, "a data transfer length of zero but no status to send is wrong\n");
1117 ccb->ccb_h.status = CAM_REQ_INVALID;
1118 xpt_done(ccb);
1119 continue;
1120 }
1121 }
1122
1123 atp = isp_find_atpd(isp, XS_CHANNEL(ccb), cso->tag_id);
1124 if (atp == NULL) {
1125 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find private data adjunct in %s", __func__, cso->tag_id, __func__);
1126 isp_dump_atpd(isp, XS_CHANNEL(ccb));
1127 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1128 xpt_done(ccb);
1129 continue;
1130 }
1131
1132 /*
1133 * Is this command a dead duck?
1134 */
1135 if (atp->dead) {
1136 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] not sending a CTIO for a dead command", __func__, cso->tag_id);
1137 ccb->ccb_h.status = CAM_REQ_ABORTED;
1138 xpt_done(ccb);
1139 continue;
1140 }
1141
1142 /*
1143 * Check to make sure we're still in target mode.
1144 */
1145 fcp = FCPARAM(isp, XS_CHANNEL(ccb));
1146 if ((fcp->role & ISP_ROLE_TARGET) == 0) {
1147 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] stopping sending a CTIO because we're no longer in target mode", __func__, cso->tag_id);
1148 ccb->ccb_h.status = CAM_PROVIDE_FAIL;
1149 xpt_done(ccb);
1150 continue;
1151 }
1152
1153 /*
1154 * We're only handling ATPD_CCB_OUTSTANDING outstanding CCB at a time (one of which
1155 * could be split into two CTIOs to split data and status).
1156 */
1157 if (atp->ctcnt >= ATPD_CCB_OUTSTANDING) {
1158 isp_prt(isp, ISP_LOGTINFO, "[0x%x] handling only %d CCBs at a time (flags for this ccb: 0x%x)", cso->tag_id, ATPD_CCB_OUTSTANDING, ccb->ccb_h.flags);
1159 TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, sim_links.tqe);
1160 break;
1161 }
1162
1163 /*
1164 * Does the initiator expect FC-Tape style responses?
1165 */
1166 if ((atp->word3 & PRLI_WD3_RETRY) && fcp->fctape_enabled) {
1167 fctape = 1;
1168 } else {
1169 fctape = 0;
1170 }
1171
1172 /*
1173 * If we already did the data xfer portion of a CTIO that sends data
1174 * and status, don't do it again and do the status portion now.
1175 */
1176 if (atp->sendst) {
1177 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] now sending synthesized status orig_dl=%u xfered=%u bit=%u",
1178 cso->tag_id, atp->orig_datalen, atp->bytes_xfered, atp->bytes_in_transit);
1179 xfrlen = 0; /* we already did the data transfer */
1180 atp->sendst = 0;
1181 }
1182 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1183 sendstatus = 1;
1184 } else {
1185 sendstatus = 0;
1186 }
1187
1188 if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
1189 KASSERT((sendstatus != 0), ("how can you have CAM_SEND_SENSE w/o CAM_SEND_STATUS?"));
1190 /*
1191 * Sense length is not the entire sense data structure size. Periph
1192 * drivers don't seem to be setting sense_len to reflect the actual
1193 * size. We'll peek inside to get the right amount.
1194 */
1195 sense_length = cso->sense_len;
1196
1197 /*
1198 * This 'cannot' happen
1199 */
1200 if (sense_length > (XCMD_SIZE - MIN_FCP_RESPONSE_SIZE)) {
1201 sense_length = XCMD_SIZE - MIN_FCP_RESPONSE_SIZE;
1202 }
1203 } else {
1204 sense_length = 0;
1205 }
1206
1207 memset(local, 0, QENTRY_LEN);
1208
1209 /*
1210 * Check for overflow
1211 */
1212 tmp = atp->bytes_xfered + atp->bytes_in_transit;
1213 if (xfrlen > 0 && tmp > atp->orig_datalen) {
1214 isp_prt(isp, ISP_LOGERR,
1215 "%s: [0x%x] data overflow by %u bytes", __func__,
1216 cso->tag_id, tmp + xfrlen - atp->orig_datalen);
1217 ccb->ccb_h.status = CAM_DATA_RUN_ERR;
1218 xpt_done(ccb);
1219 continue;
1220 }
1221 if (xfrlen > atp->orig_datalen - tmp) {
1222 xfrlen = atp->orig_datalen - tmp;
1223 if (xfrlen == 0 && !sendstatus) {
1224 cso->resid = cso->dxfer_len;
1225 ccb->ccb_h.status = CAM_REQ_CMP;
1226 xpt_done(ccb);
1227 continue;
1228 }
1229 }
1230
1231 if (IS_24XX(isp)) {
1232 ct7_entry_t *cto = (ct7_entry_t *) local;
1233
1234 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
1235 cto->ct_header.rqs_entry_count = 1;
1236 cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM;
1237 ATPD_SET_SEQNO(cto, atp);
1238 cto->ct_nphdl = atp->nphdl;
1239 cto->ct_rxid = atp->tag;
1240 cto->ct_iid_lo = atp->sid;
1241 cto->ct_iid_hi = atp->sid >> 16;
1242 cto->ct_oxid = atp->oxid;
1243 cto->ct_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(ccb));
1244 cto->ct_timeout = XS_TIME(ccb);
1245 cto->ct_flags = atp->tattr << CT7_TASK_ATTR_SHIFT;
1246
1247 /*
1248 * Mode 1, status, no data. Only possible when we are sending status, have
1249 * no data to transfer, and any sense data can fit into a ct7_entry_t.
1250 *
1251 * Mode 2, status, no data. We have to use this in the case that
1252 * the sense data won't fit into a ct7_entry_t.
1253 *
1254 */
1255 if (sendstatus && xfrlen == 0) {
1256 cto->ct_flags |= CT7_SENDSTATUS | CT7_NO_DATA;
1257 resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit;
1258 if (sense_length <= MAXRESPLEN_24XX) {
1259 cto->ct_flags |= CT7_FLAG_MODE1;
1260 cto->ct_scsi_status = cso->scsi_status;
1261 if (resid < 0) {
1262 cto->ct_resid = -resid;
1263 cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8);
1264 } else if (resid > 0) {
1265 cto->ct_resid = resid;
1266 cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8);
1267 }
1268 if (fctape) {
1269 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF;
1270 }
1271 if (sense_length) {
1272 cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8);
1273 cto->rsp.m1.ct_resplen = cto->ct_senselen = sense_length;
1274 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length);
1275 }
1276 } else {
1277 bus_addr_t addr;
1278 char buf[XCMD_SIZE];
1279 fcp_rsp_iu_t *rp;
1280
1281 if (atp->ests == NULL) {
1282 atp->ests = isp_get_ecmd(isp);
1283 if (atp->ests == NULL) {
1284 TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, sim_links.tqe);
1285 break;
1286 }
1287 }
1288 memset(buf, 0, sizeof (buf));
1289 rp = (fcp_rsp_iu_t *)buf;
1290 if (fctape) {
1291 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF;
1292 rp->fcp_rsp_bits |= FCP_CONF_REQ;
1293 }
1294 cto->ct_flags |= CT7_FLAG_MODE2;
1295 rp->fcp_rsp_scsi_status = cso->scsi_status;
1296 if (resid < 0) {
1297 rp->fcp_rsp_resid = -resid;
1298 rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW;
1299 } else if (resid > 0) {
1300 rp->fcp_rsp_resid = resid;
1301 rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW;
1302 }
1303 if (sense_length) {
1304 rp->fcp_rsp_snslen = sense_length;
1305 cto->ct_senselen = sense_length;
1306 rp->fcp_rsp_bits |= FCP_SNSLEN_VALID;
1307 isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1308 memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length);
1309 } else {
1310 isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1311 }
1312 if (isp->isp_dblev & ISP_LOGTDEBUG1) {
1313 isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests);
1314 }
1315 addr = isp->isp_osinfo.ecmd_dma;
1316 addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE);
1317 isp_prt(isp, ISP_LOGTDEBUG0, "%s: ests base %p vaddr %p ecmd_dma %jx addr %jx len %u", __func__, isp->isp_osinfo.ecmd_base, atp->ests,
1318 (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length);
1319 cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length;
1320 cto->rsp.m2.ct_fcp_rsp_iudata.ds_base = DMA_LO32(addr);
1321 cto->rsp.m2.ct_fcp_rsp_iudata.ds_basehi = DMA_HI32(addr);
1322 cto->rsp.m2.ct_fcp_rsp_iudata.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length;
1323 }
1324 if (sense_length) {
1325 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d slen %u sense: %x %x/%x/%x", __func__,
1326 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, cto->ct_resid, sense_length,
1327 cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]);
1328 } else {
1329 isp_prt(isp, ISP_LOGDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d", __func__,
1330 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, cto->ct_resid);
1331 }
1332 atp->state = ATPD_STATE_LAST_CTIO;
1333 }
1334
1335 /*
1336 * Mode 0 data transfers, *possibly* with status.
1337 */
1338 if (xfrlen != 0) {
1339 cto->ct_flags |= CT7_FLAG_MODE0;
1340 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1341 cto->ct_flags |= CT7_DATA_IN;
1342 } else {
1343 cto->ct_flags |= CT7_DATA_OUT;
1344 }
1345
1346 cto->rsp.m0.reloff = atp->bytes_xfered + atp->bytes_in_transit;
1347 cto->rsp.m0.ct_xfrlen = xfrlen;
1348
1349 #ifdef DEBUG
1350 if (ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame && xfrlen > ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame) {
1351 isp_prt(isp, ISP_LOGWARN, "%s: truncating data frame with xfrlen %d to %d", __func__, xfrlen, xfrlen - (xfrlen >> 2));
1352 ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame = 0;
1353 cto->rsp.m0.ct_xfrlen -= xfrlen >> 2;
1354 }
1355 #endif
1356 if (sendstatus) {
1357 resid = atp->orig_datalen - atp->bytes_xfered - xfrlen;
1358 if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /* && fctape == 0 */) {
1359 cto->ct_flags |= CT7_SENDSTATUS;
1360 atp->state = ATPD_STATE_LAST_CTIO;
1361 if (fctape) {
1362 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF;
1363 }
1364 } else {
1365 atp->sendst = 1; /* send status later */
1366 cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM;
1367 atp->state = ATPD_STATE_CTIO;
1368 }
1369 } else {
1370 atp->state = ATPD_STATE_CTIO;
1371 }
1372 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x xfrlen=%u off=%u", __func__,
1373 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, xfrlen, atp->bytes_xfered);
1374 }
1375 } else {
1376 ct2_entry_t *cto = (ct2_entry_t *) local;
1377
1378 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
1379 cto->ct_header.rqs_entry_count = 1;
1380 cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM;
1381 ATPD_SET_SEQNO(cto, atp);
1382 if (ISP_CAP_2KLOGIN(isp)) {
1383 ((ct2e_entry_t *)cto)->ct_iid = atp->nphdl;
1384 } else {
1385 cto->ct_iid = atp->nphdl;
1386 if (ISP_CAP_SCCFW(isp) == 0) {
1387 cto->ct_lun = ccb->ccb_h.target_lun;
1388 }
1389 }
1390 cto->ct_timeout = XS_TIME(ccb);
1391 cto->ct_rxid = cso->tag_id;
1392
1393 /*
1394 * Mode 1, status, no data. Only possible when we are sending status, have
1395 * no data to transfer, and the sense length can fit in the ct7_entry.
1396 *
1397 * Mode 2, status, no data. We have to use this in the case the response
1398 * length won't fit into a ct2_entry_t.
1399 *
1400 * We'll fill out this structure with information as if this were a
1401 * Mode 1. The hardware layer will create the Mode 2 FCP RSP IU as
1402 * needed based upon this.
1403 */
1404 if (sendstatus && xfrlen == 0) {
1405 cto->ct_flags |= CT2_SENDSTATUS | CT2_NO_DATA;
1406 resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit;
1407 if (sense_length <= MAXRESPLEN) {
1408 if (resid < 0) {
1409 cto->ct_resid = -resid;
1410 } else if (resid > 0) {
1411 cto->ct_resid = resid;
1412 }
1413 cto->ct_flags |= CT2_FLAG_MODE1;
1414 cto->rsp.m1.ct_scsi_status = cso->scsi_status;
1415 if (resid < 0) {
1416 cto->rsp.m1.ct_scsi_status |= CT2_DATA_OVER;
1417 } else if (resid > 0) {
1418 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
1419 }
1420 if (fctape) {
1421 cto->ct_flags |= CT2_CONFIRM;
1422 }
1423 if (sense_length) {
1424 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
1425 cto->rsp.m1.ct_resplen = cto->rsp.m1.ct_senselen = sense_length;
1426 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length);
1427 }
1428 } else {
1429 bus_addr_t addr;
1430 char buf[XCMD_SIZE];
1431 fcp_rsp_iu_t *rp;
1432
1433 if (atp->ests == NULL) {
1434 atp->ests = isp_get_ecmd(isp);
1435 if (atp->ests == NULL) {
1436 TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, sim_links.tqe);
1437 break;
1438 }
1439 }
1440 memset(buf, 0, sizeof (buf));
1441 rp = (fcp_rsp_iu_t *)buf;
1442 if (fctape) {
1443 cto->ct_flags |= CT2_CONFIRM;
1444 rp->fcp_rsp_bits |= FCP_CONF_REQ;
1445 }
1446 cto->ct_flags |= CT2_FLAG_MODE2;
1447 rp->fcp_rsp_scsi_status = cso->scsi_status;
1448 if (resid < 0) {
1449 rp->fcp_rsp_resid = -resid;
1450 rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW;
1451 } else if (resid > 0) {
1452 rp->fcp_rsp_resid = resid;
1453 rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW;
1454 }
1455 if (sense_length) {
1456 rp->fcp_rsp_snslen = sense_length;
1457 rp->fcp_rsp_bits |= FCP_SNSLEN_VALID;
1458 isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1459 memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length);
1460 } else {
1461 isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1462 }
1463 if (isp->isp_dblev & ISP_LOGTDEBUG1) {
1464 isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests);
1465 }
1466 addr = isp->isp_osinfo.ecmd_dma;
1467 addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE);
1468 isp_prt(isp, ISP_LOGTDEBUG0, "%s: ests base %p vaddr %p ecmd_dma %jx addr %jx len %u", __func__, isp->isp_osinfo.ecmd_base, atp->ests,
1469 (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length);
1470 cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length;
1471 cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_base = DMA_LO32(addr);
1472 cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length;
1473 }
1474 if (sense_length) {
1475 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d sense: %x %x/%x/%x", __func__,
1476 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid,
1477 cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]);
1478 } else {
1479 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d", __func__, cto->ct_rxid,
1480 ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid);
1481 }
1482 atp->state = ATPD_STATE_LAST_CTIO;
1483 }
1484
1485 if (xfrlen != 0) {
1486 cto->ct_flags |= CT2_FLAG_MODE0;
1487 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1488 cto->ct_flags |= CT2_DATA_IN;
1489 } else {
1490 cto->ct_flags |= CT2_DATA_OUT;
1491 }
1492
1493 cto->ct_reloff = atp->bytes_xfered + atp->bytes_in_transit;
1494 cto->rsp.m0.ct_xfrlen = xfrlen;
1495
1496 if (sendstatus) {
1497 resid = atp->orig_datalen - atp->bytes_xfered - xfrlen;
1498 if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /*&& fctape == 0*/) {
1499 cto->ct_flags |= CT2_SENDSTATUS;
1500 atp->state = ATPD_STATE_LAST_CTIO;
1501 if (fctape) {
1502 cto->ct_flags |= CT2_CONFIRM;
1503 }
1504 } else {
1505 atp->sendst = 1; /* send status later */
1506 cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM;
1507 atp->state = ATPD_STATE_CTIO;
1508 }
1509 } else {
1510 atp->state = ATPD_STATE_CTIO;
1511 }
1512 }
1513 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[%x] seq %u nc %d CDB0=%x scsi status %x flags %x resid %d xfrlen %u offset %u", __func__, cto->ct_rxid,
1514 ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid, cso->dxfer_len, atp->bytes_xfered);
1515 }
1516
1517 if (isp_get_pcmd(isp, ccb)) {
1518 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "out of PCMDs\n");
1519 TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, sim_links.tqe);
1520 break;
1521 }
1522 handle = isp_allocate_handle(isp, ccb, ISP_HANDLE_TARGET);
1523 if (handle == 0) {
1524 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__);
1525 TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, sim_links.tqe);
1526 isp_free_pcmd(isp, ccb);
1527 break;
1528 }
1529 atp->bytes_in_transit += xfrlen;
1530 PISP_PCMD(ccb)->datalen = xfrlen;
1531
1532
1533 /*
1534 * Call the dma setup routines for this entry (and any subsequent
1535 * CTIOs) if there's data to move, and then tell the f/w it's got
1536 * new things to play with. As with isp_start's usage of DMA setup,
1537 * any swizzling is done in the machine dependent layer. Because
1538 * of this, we put the request onto the queue area first in native
1539 * format.
1540 */
1541
1542 if (IS_24XX(isp)) {
1543 ct7_entry_t *cto = (ct7_entry_t *) local;
1544 cto->ct_syshandle = handle;
1545 } else {
1546 ct2_entry_t *cto = (ct2_entry_t *) local;
1547 cto->ct_syshandle = handle;
1548 }
1549
1550 dmaresult = ISP_DMASETUP(isp, cso, (ispreq_t *) local);
1551 if (dmaresult != CMD_QUEUED) {
1552 isp_destroy_handle(isp, handle);
1553 isp_free_pcmd(isp, ccb);
1554 if (dmaresult == CMD_EAGAIN) {
1555 TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, sim_links.tqe);
1556 break;
1557 }
1558 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1559 xpt_done(ccb);
1560 continue;
1561 }
1562 ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED;
1563 if (xfrlen) {
1564 ccb->ccb_h.spriv_field0 = atp->bytes_xfered;
1565 } else {
1566 ccb->ccb_h.spriv_field0 = ~0;
1567 }
1568 atp->ctcnt++;
1569 atp->seqno++;
1570 }
1571 }
1572
1573 static void
isp_refire_putback_atio(void * arg)1574 isp_refire_putback_atio(void *arg)
1575 {
1576 union ccb *ccb = arg;
1577
1578 ISP_ASSERT_LOCKED((ispsoftc_t *)XS_ISP(ccb));
1579 isp_target_putback_atio(ccb);
1580 }
1581
1582 static void
isp_refire_notify_ack(void * arg)1583 isp_refire_notify_ack(void *arg)
1584 {
1585 isp_tna_t *tp = arg;
1586 ispsoftc_t *isp = tp->isp;
1587
1588 ISP_ASSERT_LOCKED(isp);
1589 if (isp_notify_ack(isp, tp->not)) {
1590 callout_schedule(&tp->timer, 5);
1591 } else {
1592 free(tp, M_DEVBUF);
1593 }
1594 }
1595
1596
1597 static void
isp_target_putback_atio(union ccb * ccb)1598 isp_target_putback_atio(union ccb *ccb)
1599 {
1600 ispsoftc_t *isp = XS_ISP(ccb);
1601 struct ccb_scsiio *cso = &ccb->csio;
1602 at2_entry_t local, *at = &local;
1603
1604 ISP_MEMZERO(at, sizeof (at2_entry_t));
1605 at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
1606 at->at_header.rqs_entry_count = 1;
1607 if (ISP_CAP_SCCFW(isp)) {
1608 at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
1609 } else {
1610 at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
1611 }
1612 at->at_status = CT_OK;
1613 at->at_rxid = cso->tag_id;
1614 at->at_iid = cso->init_id;
1615 if (isp_target_put_entry(isp, at)) {
1616 callout_reset(&PISP_PCMD(ccb)->wdog, 10,
1617 isp_refire_putback_atio, ccb);
1618 } else
1619 isp_complete_ctio(ccb);
1620 }
1621
1622 static void
isp_complete_ctio(union ccb * ccb)1623 isp_complete_ctio(union ccb *ccb)
1624 {
1625 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
1626 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1627 xpt_done(ccb);
1628 }
1629 }
1630
1631 static void
isp_handle_platform_atio2(ispsoftc_t * isp,at2_entry_t * aep)1632 isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1633 {
1634 fcparam *fcp;
1635 lun_id_t lun;
1636 fcportdb_t *lp;
1637 tstate_t *tptr;
1638 struct ccb_accept_tio *atiop;
1639 uint16_t nphdl;
1640 atio_private_data_t *atp;
1641 inot_private_data_t *ntp;
1642
1643 /*
1644 * The firmware status (except for the QLTM_SVALID bit)
1645 * indicates why this ATIO was sent to us.
1646 *
1647 * If QLTM_SVALID is set, the firmware has recommended Sense Data.
1648 */
1649 if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
1650 isp_prt(isp, ISP_LOGWARN, "bogus atio (0x%x) leaked to platform", aep->at_status);
1651 isp_endcmd(isp, aep, NIL_HANDLE, 0, SCSI_STATUS_BUSY, 0);
1652 return;
1653 }
1654
1655 fcp = FCPARAM(isp, 0);
1656 if (ISP_CAP_SCCFW(isp)) {
1657 lun = aep->at_scclun;
1658 } else {
1659 lun = aep->at_lun;
1660 }
1661 if (ISP_CAP_2KLOGIN(isp)) {
1662 nphdl = ((at2e_entry_t *)aep)->at_iid;
1663 } else {
1664 nphdl = aep->at_iid;
1665 }
1666 tptr = get_lun_statep(isp, 0, lun);
1667 if (tptr == NULL) {
1668 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
1669 if (tptr == NULL) {
1670 isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %jx or wildcard", __func__, aep->at_rxid, (uintmax_t)lun);
1671 if (lun == 0) {
1672 isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
1673 } else {
1674 isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
1675 }
1676 return;
1677 }
1678 }
1679
1680 /*
1681 * Start any commands pending resources first.
1682 */
1683 if (isp_atio_restart(isp, 0, tptr))
1684 goto noresrc;
1685
1686 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1687 if (atiop == NULL) {
1688 goto noresrc;
1689 }
1690
1691 atp = isp_get_atpd(isp, 0, aep->at_rxid);
1692 if (atp == NULL) {
1693 goto noresrc;
1694 }
1695
1696 atp->state = ATPD_STATE_ATIO;
1697 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1698 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO\n");
1699 atiop->ccb_h.target_id = ISP_MAX_TARGETS(isp);
1700 atiop->ccb_h.target_lun = lun;
1701
1702 /*
1703 * We don't get 'suggested' sense data as we do with SCSI cards.
1704 */
1705 atiop->sense_len = 0;
1706
1707 /*
1708 * If we're not in the port database, add ourselves.
1709 */
1710 if (IS_2100(isp))
1711 atiop->init_id = nphdl;
1712 else {
1713 if (isp_find_pdb_by_handle(isp, 0, nphdl, &lp)) {
1714 atiop->init_id = FC_PORTDB_TGT(isp, 0, lp);
1715 } else {
1716 isp_prt(isp, ISP_LOGTINFO, "%s: port %x isn't in PDB",
1717 __func__, nphdl);
1718 isp_dump_portdb(isp, 0);
1719 isp_endcmd(isp, aep, NIL_HANDLE, 0, ECMD_TERMINATE, 0);
1720 return;
1721 }
1722 }
1723 atiop->cdb_len = ATIO2_CDBLEN;
1724 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
1725 atiop->ccb_h.status = CAM_CDB_RECVD;
1726 atiop->tag_id = atp->tag;
1727 switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
1728 case ATIO2_TC_ATTR_SIMPLEQ:
1729 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1730 atiop->tag_action = MSG_SIMPLE_Q_TAG;
1731 break;
1732 case ATIO2_TC_ATTR_HEADOFQ:
1733 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1734 atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1735 break;
1736 case ATIO2_TC_ATTR_ORDERED:
1737 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1738 atiop->tag_action = MSG_ORDERED_Q_TAG;
1739 break;
1740 case ATIO2_TC_ATTR_ACAQ: /* ?? */
1741 case ATIO2_TC_ATTR_UNTAGGED:
1742 default:
1743 atiop->tag_action = 0;
1744 break;
1745 }
1746
1747 atp->orig_datalen = aep->at_datalen;
1748 atp->bytes_xfered = 0;
1749 atp->lun = lun;
1750 atp->nphdl = nphdl;
1751 atp->sid = PORT_ANY;
1752 atp->oxid = aep->at_oxid;
1753 atp->cdb0 = aep->at_cdb[0];
1754 atp->tattr = aep->at_taskflags & ATIO2_TC_ATTR_MASK;
1755 atp->state = ATPD_STATE_CAM;
1756 xpt_done((union ccb *)atiop);
1757 isp_prt(isp, ISP_LOGTDEBUG0, "ATIO2[0x%x] CDB=0x%x lun %jx datalen %u", aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen);
1758 return;
1759 noresrc:
1760 ntp = isp_get_ntpd(isp, 0);
1761 if (ntp == NULL) {
1762 isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
1763 return;
1764 }
1765 memcpy(ntp->data, aep, QENTRY_LEN);
1766 STAILQ_INSERT_TAIL(&tptr->restart_queue, ntp, next);
1767 }
1768
1769 static void
isp_handle_platform_atio7(ispsoftc_t * isp,at7_entry_t * aep)1770 isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
1771 {
1772 int cdbxlen;
1773 lun_id_t lun;
1774 uint16_t chan, nphdl = NIL_HANDLE;
1775 uint32_t did, sid;
1776 fcportdb_t *lp;
1777 tstate_t *tptr;
1778 struct ccb_accept_tio *atiop;
1779 atio_private_data_t *atp = NULL;
1780 atio_private_data_t *oatp;
1781 inot_private_data_t *ntp;
1782
1783 did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2];
1784 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
1785 lun = CAM_EXTLUN_BYTE_SWIZZLE(be64dec(aep->at_cmnd.fcp_cmnd_lun));
1786
1787 if (ISP_CAP_MULTI_ID(isp) && isp->isp_nchan > 1) {
1788 /* Channel has to be derived from D_ID */
1789 isp_find_chan_by_did(isp, did, &chan);
1790 if (chan == ISP_NOCHAN) {
1791 isp_prt(isp, ISP_LOGWARN,
1792 "%s: [RX_ID 0x%x] D_ID %x not found on any channel",
1793 __func__, aep->at_rxid, did);
1794 isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN,
1795 ECMD_TERMINATE, 0);
1796 return;
1797 }
1798 } else {
1799 chan = 0;
1800 }
1801
1802 /*
1803 * Find the PDB entry for this initiator
1804 */
1805 if (isp_find_pdb_by_portid(isp, chan, sid, &lp) == 0) {
1806 /*
1807 * If we're not in the port database terminate the exchange.
1808 */
1809 isp_prt(isp, ISP_LOGTINFO, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x wasn't in PDB already",
1810 __func__, aep->at_rxid, did, chan, sid);
1811 isp_dump_portdb(isp, chan);
1812 isp_endcmd(isp, aep, NIL_HANDLE, chan, ECMD_TERMINATE, 0);
1813 return;
1814 }
1815 nphdl = lp->handle;
1816
1817 /*
1818 * Get the tstate pointer
1819 */
1820 tptr = get_lun_statep(isp, chan, lun);
1821 if (tptr == NULL) {
1822 tptr = get_lun_statep(isp, chan, CAM_LUN_WILDCARD);
1823 if (tptr == NULL) {
1824 isp_prt(isp, ISP_LOGWARN,
1825 "%s: [0x%x] no state pointer for lun %jx or wildcard",
1826 __func__, aep->at_rxid, (uintmax_t)lun);
1827 if (lun == 0) {
1828 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
1829 } else {
1830 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
1831 }
1832 return;
1833 }
1834 }
1835
1836 /*
1837 * Start any commands pending resources first.
1838 */
1839 if (isp_atio_restart(isp, chan, tptr))
1840 goto noresrc;
1841
1842 /*
1843 * If the f/w is out of resources, just send a BUSY status back.
1844 */
1845 if (aep->at_rxid == AT7_NORESRC_RXID) {
1846 isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
1847 return;
1848 }
1849
1850 /*
1851 * If we're out of resources, just send a BUSY status back.
1852 */
1853 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1854 if (atiop == NULL) {
1855 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atios", aep->at_rxid);
1856 goto noresrc;
1857 }
1858
1859 oatp = isp_find_atpd(isp, chan, aep->at_rxid);
1860 if (oatp) {
1861 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] tag wraparound in isp_handle_platforms_atio7 (N-Port Handle 0x%04x S_ID 0x%04x OX_ID 0x%04x) oatp state %d",
1862 aep->at_rxid, nphdl, sid, aep->at_hdr.ox_id, oatp->state);
1863 /*
1864 * It's not a "no resource" condition- but we can treat it like one
1865 */
1866 goto noresrc;
1867 }
1868 atp = isp_get_atpd(isp, chan, aep->at_rxid);
1869 if (atp == NULL) {
1870 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atps", aep->at_rxid);
1871 goto noresrc;
1872 }
1873 atp->word3 = lp->prli_word3;
1874 atp->state = ATPD_STATE_ATIO;
1875 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1876 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO\n");
1877 atiop->init_id = FC_PORTDB_TGT(isp, chan, lp);
1878 atiop->ccb_h.target_id = ISP_MAX_TARGETS(isp);
1879 atiop->ccb_h.target_lun = lun;
1880 atiop->sense_len = 0;
1881 cdbxlen = aep->at_cmnd.fcp_cmnd_alen_datadir >> FCP_CMND_ADDTL_CDBLEN_SHIFT;
1882 if (cdbxlen) {
1883 isp_prt(isp, ISP_LOGWARN, "additional CDBLEN ignored");
1884 }
1885 cdbxlen = sizeof (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb);
1886 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb, cdbxlen);
1887 atiop->cdb_len = cdbxlen;
1888 atiop->ccb_h.status = CAM_CDB_RECVD;
1889 atiop->tag_id = atp->tag;
1890 switch (aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK) {
1891 case FCP_CMND_TASK_ATTR_SIMPLE:
1892 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1893 atiop->tag_action = MSG_SIMPLE_Q_TAG;
1894 break;
1895 case FCP_CMND_TASK_ATTR_HEAD:
1896 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1897 atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1898 break;
1899 case FCP_CMND_TASK_ATTR_ORDERED:
1900 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1901 atiop->tag_action = MSG_ORDERED_Q_TAG;
1902 break;
1903 default:
1904 /* FALLTHROUGH */
1905 case FCP_CMND_TASK_ATTR_ACA:
1906 case FCP_CMND_TASK_ATTR_UNTAGGED:
1907 atiop->tag_action = 0;
1908 break;
1909 }
1910 atiop->priority = (aep->at_cmnd.fcp_cmnd_task_attribute &
1911 FCP_CMND_PRIO_MASK) >> FCP_CMND_PRIO_SHIFT;
1912 atp->orig_datalen = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
1913 atp->bytes_xfered = 0;
1914 atp->lun = lun;
1915 atp->nphdl = nphdl;
1916 atp->sid = sid;
1917 atp->did = did;
1918 atp->oxid = aep->at_hdr.ox_id;
1919 atp->rxid = aep->at_hdr.rx_id;
1920 atp->cdb0 = atiop->cdb_io.cdb_bytes[0];
1921 atp->tattr = aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK;
1922 atp->state = ATPD_STATE_CAM;
1923 isp_prt(isp, ISP_LOGTDEBUG0, "ATIO7[0x%x] CDB=0x%x lun %jx datalen %u",
1924 aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen);
1925 xpt_done((union ccb *)atiop);
1926 return;
1927 noresrc:
1928 if (atp)
1929 isp_put_atpd(isp, chan, atp);
1930 ntp = isp_get_ntpd(isp, chan);
1931 if (ntp == NULL) {
1932 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
1933 return;
1934 }
1935 memcpy(ntp->data, aep, QENTRY_LEN);
1936 STAILQ_INSERT_TAIL(&tptr->restart_queue, ntp, next);
1937 }
1938
1939
1940 /*
1941 * Handle starting an SRR (sequence retransmit request)
1942 * We get here when we've gotten the immediate notify
1943 * and the return of all outstanding CTIOs for this
1944 * transaction.
1945 */
1946 static void
isp_handle_srr_start(ispsoftc_t * isp,atio_private_data_t * atp)1947 isp_handle_srr_start(ispsoftc_t *isp, atio_private_data_t *atp)
1948 {
1949 in_fcentry_24xx_t *inot;
1950 uint32_t srr_off, ccb_off, ccb_len, ccb_end;
1951 union ccb *ccb;
1952
1953 inot = (in_fcentry_24xx_t *)atp->srr;
1954 srr_off = inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16);
1955 ccb = atp->srr_ccb;
1956 atp->srr_ccb = NULL;
1957 atp->nsrr++;
1958 if (ccb == NULL) {
1959 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] null ccb", atp->tag);
1960 goto fail;
1961 }
1962
1963 ccb_off = ccb->ccb_h.spriv_field0;
1964 ccb_len = ccb->csio.dxfer_len;
1965 ccb_end = (ccb_off == ~0)? ~0 : ccb_off + ccb_len;
1966
1967 switch (inot->in_srr_iu) {
1968 case R_CTL_INFO_SOLICITED_DATA:
1969 /*
1970 * We have to restart a FCP_DATA data out transaction
1971 */
1972 atp->sendst = 0;
1973 atp->bytes_xfered = srr_off;
1974 if (ccb_len == 0) {
1975 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x but current CCB doesn't transfer data", atp->tag, srr_off);
1976 goto mdp;
1977 }
1978 if (srr_off < ccb_off || ccb_off > srr_off + ccb_len) {
1979 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x not covered by current CCB data range [0x%x..0x%x]", atp->tag, srr_off, ccb_off, ccb_end);
1980 goto mdp;
1981 }
1982 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x covered by current CCB data range [0x%x..0x%x]", atp->tag, srr_off, ccb_off, ccb_end);
1983 break;
1984 case R_CTL_INFO_COMMAND_STATUS:
1985 isp_prt(isp, ISP_LOGTINFO, "SRR[0x%x] Got an FCP RSP SRR- resending status", atp->tag);
1986 atp->sendst = 1;
1987 /*
1988 * We have to restart a FCP_RSP IU transaction
1989 */
1990 break;
1991 case R_CTL_INFO_DATA_DESCRIPTOR:
1992 /*
1993 * We have to restart an FCP DATA in transaction
1994 */
1995 isp_prt(isp, ISP_LOGWARN, "Got an FCP DATA IN SRR- dropping");
1996 goto fail;
1997
1998 default:
1999 isp_prt(isp, ISP_LOGWARN, "Got an unknown information (%x) SRR- dropping", inot->in_srr_iu);
2000 goto fail;
2001 }
2002
2003 /*
2004 * We can't do anything until this is acked, so we might as well start it now.
2005 * We aren't going to do the usual asynchronous ack issue because we need
2006 * to make sure this gets on the wire first.
2007 */
2008 if (isp_notify_ack(isp, inot)) {
2009 isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose");
2010 goto fail;
2011 }
2012 isp_target_start_ctio(isp, ccb, FROM_SRR);
2013 return;
2014 fail:
2015 inot->in_reserved = 1;
2016 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
2017 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2018 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
2019 isp_complete_ctio(ccb);
2020 return;
2021 mdp:
2022 if (isp_notify_ack(isp, inot)) {
2023 isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose");
2024 goto fail;
2025 }
2026 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2027 ccb->ccb_h.status = CAM_MESSAGE_RECV;
2028 /*
2029 * This is not a strict interpretation of MDP, but it's close
2030 */
2031 ccb->csio.msg_ptr = &ccb->csio.sense_data.sense_buf[SSD_FULL_SIZE - 16];
2032 ccb->csio.msg_len = 7;
2033 ccb->csio.msg_ptr[0] = MSG_EXTENDED;
2034 ccb->csio.msg_ptr[1] = 5;
2035 ccb->csio.msg_ptr[2] = 0; /* modify data pointer */
2036 ccb->csio.msg_ptr[3] = srr_off >> 24;
2037 ccb->csio.msg_ptr[4] = srr_off >> 16;
2038 ccb->csio.msg_ptr[5] = srr_off >> 8;
2039 ccb->csio.msg_ptr[6] = srr_off;
2040 isp_complete_ctio(ccb);
2041 }
2042
2043
2044 static void
isp_handle_platform_srr(ispsoftc_t * isp,isp_notify_t * notify)2045 isp_handle_platform_srr(ispsoftc_t *isp, isp_notify_t *notify)
2046 {
2047 in_fcentry_24xx_t *inot = notify->nt_lreserved;
2048 atio_private_data_t *atp;
2049 uint32_t tag = notify->nt_tagval & 0xffffffff;
2050
2051 atp = isp_find_atpd(isp, notify->nt_channel, tag);
2052 if (atp == NULL) {
2053 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify",
2054 __func__, tag);
2055 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
2056 return;
2057 }
2058 atp->srr_notify_rcvd = 1;
2059 memcpy(atp->srr, inot, sizeof (atp->srr));
2060 isp_prt(isp, ISP_LOGTINFO, "SRR[0x%x] flags 0x%x srr_iu %x reloff 0x%x",
2061 inot->in_rxid, inot->in_flags, inot->in_srr_iu,
2062 ((uint32_t)inot->in_srr_reloff_hi << 16) | inot->in_srr_reloff_lo);
2063 if (atp->srr_ccb)
2064 isp_handle_srr_start(isp, atp);
2065 }
2066
2067 static void
isp_handle_platform_ctio(ispsoftc_t * isp,void * arg)2068 isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
2069 {
2070 union ccb *ccb;
2071 int sentstatus = 0, ok = 0, notify_cam = 0, failure = 0;
2072 atio_private_data_t *atp = NULL;
2073 int bus;
2074 uint32_t handle, data_requested, resid;
2075
2076 handle = ((ct2_entry_t *)arg)->ct_syshandle;
2077 ccb = isp_find_xs(isp, handle);
2078 if (ccb == NULL) {
2079 isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg);
2080 return;
2081 }
2082 isp_destroy_handle(isp, handle);
2083 resid = data_requested = PISP_PCMD(ccb)->datalen;
2084 isp_free_pcmd(isp, ccb);
2085
2086 bus = XS_CHANNEL(ccb);
2087 if (IS_24XX(isp)) {
2088 atp = isp_find_atpd(isp, bus, ((ct7_entry_t *)arg)->ct_rxid);
2089 } else {
2090 atp = isp_find_atpd(isp, bus, ((ct2_entry_t *)arg)->ct_rxid);
2091 }
2092 if (atp == NULL) {
2093 /*
2094 * XXX: isp_clear_commands() generates fake CTIO with zero
2095 * ct_rxid value, filling only ct_syshandle. Workaround
2096 * that using tag_id from the CCB, pointed by ct_syshandle.
2097 */
2098 atp = isp_find_atpd(isp, bus, ccb->csio.tag_id);
2099 }
2100 if (atp == NULL) {
2101 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ccb->csio.tag_id);
2102 return;
2103 }
2104 KASSERT((atp->ctcnt > 0), ("ctio count not greater than zero"));
2105 atp->bytes_in_transit -= data_requested;
2106 atp->ctcnt -= 1;
2107 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2108
2109 if (IS_24XX(isp)) {
2110 ct7_entry_t *ct = arg;
2111
2112 if (ct->ct_nphdl == CT7_SRR) {
2113 atp->srr_ccb = ccb;
2114 if (atp->srr_notify_rcvd)
2115 isp_handle_srr_start(isp, atp);
2116 return;
2117 }
2118 if (ct->ct_nphdl == CT_HBA_RESET) {
2119 sentstatus = (ccb->ccb_h.flags & CAM_SEND_STATUS) &&
2120 (atp->sendst == 0);
2121 failure = CAM_UNREC_HBA_ERROR;
2122 } else {
2123 sentstatus = ct->ct_flags & CT7_SENDSTATUS;
2124 ok = (ct->ct_nphdl == CT7_OK);
2125 notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0;
2126 if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA)
2127 resid = ct->ct_resid;
2128 }
2129 isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO7[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct),
2130 notify_cam, ct->ct_nphdl, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
2131 } else {
2132 ct2_entry_t *ct = arg;
2133 if (ct->ct_status == CT_SRR) {
2134 atp->srr_ccb = ccb;
2135 if (atp->srr_notify_rcvd)
2136 isp_handle_srr_start(isp, atp);
2137 isp_target_putback_atio(ccb);
2138 return;
2139 }
2140 if (ct->ct_status == CT_HBA_RESET) {
2141 sentstatus = (ccb->ccb_h.flags & CAM_SEND_STATUS) &&
2142 (atp->sendst == 0);
2143 failure = CAM_UNREC_HBA_ERROR;
2144 } else {
2145 sentstatus = ct->ct_flags & CT2_SENDSTATUS;
2146 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
2147 notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0;
2148 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA)
2149 resid = ct->ct_resid;
2150 }
2151 isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO2[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct),
2152 notify_cam, ct->ct_status, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
2153 }
2154 if (ok) {
2155 if (data_requested > 0) {
2156 atp->bytes_xfered += data_requested - resid;
2157 ccb->csio.resid = ccb->csio.dxfer_len -
2158 (data_requested - resid);
2159 }
2160 if (sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE))
2161 ccb->ccb_h.status |= CAM_SENT_SENSE;
2162 ccb->ccb_h.status |= CAM_REQ_CMP;
2163 } else {
2164 notify_cam = 1;
2165 if (failure == CAM_UNREC_HBA_ERROR)
2166 ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR;
2167 else
2168 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
2169 }
2170 atp->state = ATPD_STATE_PDON;
2171
2172 /*
2173 * We never *not* notify CAM when there has been any error (ok == 0),
2174 * so we never need to do an ATIO putback if we're not notifying CAM.
2175 */
2176 isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done (ok=%d nc=%d nowsendstatus=%d ccb ss=%d)",
2177 (sentstatus)? " FINAL " : "MIDTERM ", atp->tag, ok, notify_cam, atp->sendst, (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0);
2178 if (notify_cam == 0) {
2179 if (atp->sendst) {
2180 isp_target_start_ctio(isp, ccb, FROM_CTIO_DONE);
2181 }
2182 return;
2183 }
2184
2185 /*
2186 * We are done with this ATIO if we successfully sent status.
2187 * In all other cases expect either another CTIO or XPT_ABORT.
2188 */
2189 if (ok && sentstatus)
2190 isp_put_atpd(isp, bus, atp);
2191
2192 /*
2193 * We're telling CAM we're done with this CTIO transaction.
2194 *
2195 * 24XX cards never need an ATIO put back.
2196 *
2197 * Other cards need one put back only on error.
2198 * In the latter case, a timeout will re-fire
2199 * and try again in case we didn't have
2200 * queue resources to do so at first. In any case,
2201 * once the putback is done we do the completion
2202 * call.
2203 */
2204 if (ok || IS_24XX(isp)) {
2205 isp_complete_ctio(ccb);
2206 } else {
2207 isp_target_putback_atio(ccb);
2208 }
2209 }
2210
2211 static int
isp_handle_platform_target_notify_ack(ispsoftc_t * isp,isp_notify_t * mp,uint32_t rsp)2212 isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp, uint32_t rsp)
2213 {
2214
2215 if (isp->isp_state != ISP_RUNSTATE) {
2216 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", mp->nt_ncode, mp->nt_lreserved != NULL);
2217 return (0);
2218 }
2219
2220 /*
2221 * This case is for a Task Management Function, which shows up as an ATIO7 entry.
2222 */
2223 if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ATIO) {
2224 ct7_entry_t local, *cto = &local;
2225 at7_entry_t *aep = (at7_entry_t *)mp->nt_lreserved;
2226 fcportdb_t *lp;
2227 uint32_t sid;
2228 uint16_t nphdl;
2229
2230 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
2231 if (isp_find_pdb_by_portid(isp, mp->nt_channel, sid, &lp)) {
2232 nphdl = lp->handle;
2233 } else {
2234 nphdl = NIL_HANDLE;
2235 }
2236 ISP_MEMZERO(&local, sizeof (local));
2237 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
2238 cto->ct_header.rqs_entry_count = 1;
2239 cto->ct_nphdl = nphdl;
2240 cto->ct_rxid = aep->at_rxid;
2241 cto->ct_vpidx = mp->nt_channel;
2242 cto->ct_iid_lo = sid;
2243 cto->ct_iid_hi = sid >> 16;
2244 cto->ct_oxid = aep->at_hdr.ox_id;
2245 cto->ct_flags = CT7_SENDSTATUS|CT7_NOACK|CT7_NO_DATA|CT7_FLAG_MODE1;
2246 cto->ct_flags |= (aep->at_ta_len >> 12) << CT7_TASK_ATTR_SHIFT;
2247 if (rsp != 0) {
2248 cto->ct_scsi_status |= (FCP_RSPLEN_VALID << 8);
2249 cto->rsp.m1.ct_resplen = 4;
2250 ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp));
2251 cto->rsp.m1.ct_resp[0] = rsp & 0xff;
2252 cto->rsp.m1.ct_resp[1] = (rsp >> 8) & 0xff;
2253 cto->rsp.m1.ct_resp[2] = (rsp >> 16) & 0xff;
2254 cto->rsp.m1.ct_resp[3] = (rsp >> 24) & 0xff;
2255 }
2256 return (isp_target_put_entry(isp, &local));
2257 }
2258
2259 /*
2260 * This case is for a responding to an ABTS frame
2261 */
2262 if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
2263
2264 /*
2265 * Overload nt_need_ack here to mark whether we've terminated the associated command.
2266 */
2267 if (mp->nt_need_ack) {
2268 uint8_t storage[QENTRY_LEN];
2269 ct7_entry_t *cto = (ct7_entry_t *) storage;
2270 abts_t *abts = (abts_t *)mp->nt_lreserved;
2271
2272 ISP_MEMZERO(cto, sizeof (ct7_entry_t));
2273 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [%x] terminating after ABTS received", __func__, abts->abts_rxid_task);
2274 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
2275 cto->ct_header.rqs_entry_count = 1;
2276 cto->ct_nphdl = mp->nt_nphdl;
2277 cto->ct_rxid = abts->abts_rxid_task;
2278 cto->ct_iid_lo = mp->nt_sid;
2279 cto->ct_iid_hi = mp->nt_sid >> 16;
2280 cto->ct_oxid = abts->abts_ox_id;
2281 cto->ct_vpidx = mp->nt_channel;
2282 cto->ct_flags = CT7_NOACK|CT7_TERMINATE;
2283 if (isp_target_put_entry(isp, cto)) {
2284 return (ENOMEM);
2285 }
2286 mp->nt_need_ack = 0;
2287 }
2288 if (isp_acknak_abts(isp, mp->nt_lreserved, 0) == ENOMEM) {
2289 return (ENOMEM);
2290 } else {
2291 return (0);
2292 }
2293 }
2294
2295 /*
2296 * Handle logout cases here
2297 */
2298 if (mp->nt_ncode == NT_GLOBAL_LOGOUT) {
2299 isp_del_all_wwn_entries(isp, mp->nt_channel);
2300 }
2301
2302 if (mp->nt_ncode == NT_LOGOUT) {
2303 if (!IS_2100(isp) && IS_FC(isp)) {
2304 isp_del_wwn_entries(isp, mp);
2305 }
2306 }
2307
2308 /*
2309 * General purpose acknowledgement
2310 */
2311 if (mp->nt_need_ack) {
2312 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) being acked", mp->nt_ncode, mp->nt_lreserved != NULL);
2313 /*
2314 * Don't need to use the guaranteed send because the caller can retry
2315 */
2316 return (isp_notify_ack(isp, mp->nt_lreserved));
2317 }
2318 return (0);
2319 }
2320
2321 /*
2322 * Handle task management functions.
2323 *
2324 * We show up here with a notify structure filled out.
2325 *
2326 * The nt_lreserved tag points to the original queue entry
2327 */
2328 static void
isp_handle_platform_target_tmf(ispsoftc_t * isp,isp_notify_t * notify)2329 isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify)
2330 {
2331 tstate_t *tptr;
2332 fcportdb_t *lp;
2333 struct ccb_immediate_notify *inot;
2334 inot_private_data_t *ntp = NULL;
2335 atio_private_data_t *atp;
2336 lun_id_t lun;
2337
2338 isp_prt(isp, ISP_LOGTDEBUG0, "%s: code 0x%x sid 0x%x tagval 0x%016llx chan %d lun %jx", __func__, notify->nt_ncode,
2339 notify->nt_sid, (unsigned long long) notify->nt_tagval, notify->nt_channel, notify->nt_lun);
2340 if (notify->nt_lun == LUN_ANY) {
2341 if (notify->nt_tagval == TAG_ANY) {
2342 lun = CAM_LUN_WILDCARD;
2343 } else {
2344 atp = isp_find_atpd(isp, notify->nt_channel,
2345 notify->nt_tagval & 0xffffffff);
2346 lun = atp ? atp->lun : CAM_LUN_WILDCARD;
2347 }
2348 } else {
2349 lun = notify->nt_lun;
2350 }
2351 tptr = get_lun_statep(isp, notify->nt_channel, lun);
2352 if (tptr == NULL) {
2353 tptr = get_lun_statep(isp, notify->nt_channel, CAM_LUN_WILDCARD);
2354 if (tptr == NULL) {
2355 isp_prt(isp, ISP_LOGWARN, "%s: no state pointer found for chan %d lun %#jx", __func__, notify->nt_channel, (uintmax_t)lun);
2356 goto bad;
2357 }
2358 }
2359 inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots);
2360 if (inot == NULL) {
2361 isp_prt(isp, ISP_LOGWARN, "%s: out of immediate notify structures for chan %d lun %#jx", __func__, notify->nt_channel, (uintmax_t)lun);
2362 goto bad;
2363 }
2364
2365 inot->ccb_h.target_id = ISP_MAX_TARGETS(isp);
2366 inot->ccb_h.target_lun = lun;
2367 if (isp_find_pdb_by_portid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0 &&
2368 isp_find_pdb_by_handle(isp, notify->nt_channel, notify->nt_nphdl, &lp) == 0) {
2369 inot->initiator_id = CAM_TARGET_WILDCARD;
2370 } else {
2371 inot->initiator_id = FC_PORTDB_TGT(isp, notify->nt_channel, lp);
2372 }
2373 inot->seq_id = notify->nt_tagval;
2374 inot->tag_id = notify->nt_tagval >> 32;
2375
2376 switch (notify->nt_ncode) {
2377 case NT_ABORT_TASK:
2378 isp_target_mark_aborted_early(isp, notify->nt_channel, tptr, inot->tag_id);
2379 inot->arg = MSG_ABORT_TASK;
2380 break;
2381 case NT_ABORT_TASK_SET:
2382 isp_target_mark_aborted_early(isp, notify->nt_channel, tptr, TAG_ANY);
2383 inot->arg = MSG_ABORT_TASK_SET;
2384 break;
2385 case NT_CLEAR_ACA:
2386 inot->arg = MSG_CLEAR_ACA;
2387 break;
2388 case NT_CLEAR_TASK_SET:
2389 inot->arg = MSG_CLEAR_TASK_SET;
2390 break;
2391 case NT_LUN_RESET:
2392 inot->arg = MSG_LOGICAL_UNIT_RESET;
2393 break;
2394 case NT_TARGET_RESET:
2395 inot->arg = MSG_TARGET_RESET;
2396 break;
2397 case NT_QUERY_TASK_SET:
2398 inot->arg = MSG_QUERY_TASK_SET;
2399 break;
2400 case NT_QUERY_ASYNC_EVENT:
2401 inot->arg = MSG_QUERY_ASYNC_EVENT;
2402 break;
2403 default:
2404 isp_prt(isp, ISP_LOGWARN, "%s: unknown TMF code 0x%x for chan %d lun %#jx", __func__, notify->nt_ncode, notify->nt_channel, (uintmax_t)lun);
2405 goto bad;
2406 }
2407
2408 ntp = isp_get_ntpd(isp, notify->nt_channel);
2409 if (ntp == NULL) {
2410 isp_prt(isp, ISP_LOGWARN, "%s: out of inotify private structures", __func__);
2411 goto bad;
2412 }
2413 ISP_MEMCPY(&ntp->nt, notify, sizeof (isp_notify_t));
2414 if (notify->nt_lreserved) {
2415 ISP_MEMCPY(&ntp->data, notify->nt_lreserved, QENTRY_LEN);
2416 ntp->nt.nt_lreserved = &ntp->data;
2417 }
2418 ntp->seq_id = notify->nt_tagval;
2419 ntp->tag_id = notify->nt_tagval >> 32;
2420
2421 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
2422 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "Take FREE INOT\n");
2423 inot->ccb_h.status = CAM_MESSAGE_RECV;
2424 xpt_done((union ccb *)inot);
2425 return;
2426 bad:
2427 if (notify->nt_need_ack) {
2428 if (((isphdr_t *)notify->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
2429 if (isp_acknak_abts(isp, notify->nt_lreserved, ENOMEM)) {
2430 isp_prt(isp, ISP_LOGWARN, "you lose- unable to send an ACKNAK");
2431 }
2432 } else {
2433 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, notify->nt_lreserved);
2434 }
2435 }
2436 }
2437
2438 static void
isp_target_mark_aborted_early(ispsoftc_t * isp,int chan,tstate_t * tptr,uint32_t tag_id)2439 isp_target_mark_aborted_early(ispsoftc_t *isp, int chan, tstate_t *tptr, uint32_t tag_id)
2440 {
2441 atio_private_data_t *atp, *atpool;
2442 inot_private_data_t *ntp, *tmp;
2443 uint32_t this_tag_id;
2444
2445 /*
2446 * First, clean any commands pending restart
2447 */
2448 STAILQ_FOREACH_SAFE(ntp, &tptr->restart_queue, next, tmp) {
2449 if (IS_24XX(isp))
2450 this_tag_id = ((at7_entry_t *)ntp->data)->at_rxid;
2451 else
2452 this_tag_id = ((at2_entry_t *)ntp->data)->at_rxid;
2453 if ((uint64_t)tag_id == TAG_ANY || tag_id == this_tag_id) {
2454 isp_endcmd(isp, ntp->data, NIL_HANDLE, chan,
2455 ECMD_TERMINATE, 0);
2456 isp_put_ntpd(isp, chan, ntp);
2457 STAILQ_REMOVE(&tptr->restart_queue, ntp,
2458 inot_private_data, next);
2459 }
2460 }
2461
2462 /*
2463 * Now mark other ones dead as well.
2464 */
2465 ISP_GET_PC(isp, chan, atpool, atpool);
2466 for (atp = atpool; atp < &atpool[ATPDPSIZE]; atp++) {
2467 if (atp->lun != tptr->ts_lun)
2468 continue;
2469 if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id)
2470 atp->dead = 1;
2471 }
2472 }
2473 #endif
2474
2475 static void
isp_cam_async(void * cbarg,uint32_t code,struct cam_path * path,void * arg)2476 isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
2477 {
2478 struct cam_sim *sim;
2479 int bus, tgt;
2480 ispsoftc_t *isp;
2481
2482 sim = (struct cam_sim *)cbarg;
2483 isp = (ispsoftc_t *) cam_sim_softc(sim);
2484 bus = cam_sim_bus(sim);
2485 tgt = xpt_path_target_id(path);
2486
2487 switch (code) {
2488 case AC_LOST_DEVICE:
2489 if (IS_SCSI(isp)) {
2490 uint16_t oflags, nflags;
2491 sdparam *sdp = SDPARAM(isp, bus);
2492
2493 if (tgt >= 0) {
2494 nflags = sdp->isp_devparam[tgt].nvrm_flags;
2495 nflags &= DPARM_SAFE_DFLT;
2496 if (isp->isp_loaded_fw) {
2497 nflags |= DPARM_NARROW | DPARM_ASYNC;
2498 }
2499 oflags = sdp->isp_devparam[tgt].goal_flags;
2500 sdp->isp_devparam[tgt].goal_flags = nflags;
2501 sdp->isp_devparam[tgt].dev_update = 1;
2502 sdp->update = 1;
2503 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus);
2504 sdp->isp_devparam[tgt].goal_flags = oflags;
2505 }
2506 }
2507 break;
2508 default:
2509 isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code);
2510 break;
2511 }
2512 }
2513
2514 static void
isp_poll(struct cam_sim * sim)2515 isp_poll(struct cam_sim *sim)
2516 {
2517 ispsoftc_t *isp = cam_sim_softc(sim);
2518
2519 ISP_RUN_ISR(isp);
2520 }
2521
2522
2523 static void
isp_watchdog(void * arg)2524 isp_watchdog(void *arg)
2525 {
2526 struct ccb_scsiio *xs = arg;
2527 ispsoftc_t *isp;
2528 uint32_t ohandle = ISP_HANDLE_FREE, handle;
2529
2530 isp = XS_ISP(xs);
2531
2532 handle = isp_find_handle(isp, xs);
2533
2534 /*
2535 * Hand crank the interrupt code just to be sure the command isn't stuck somewhere.
2536 */
2537 if (handle != ISP_HANDLE_FREE) {
2538 ISP_RUN_ISR(isp);
2539 ohandle = handle;
2540 handle = isp_find_handle(isp, xs);
2541 }
2542 if (handle != ISP_HANDLE_FREE) {
2543 /*
2544 * Try and make sure the command is really dead before
2545 * we release the handle (and DMA resources) for reuse.
2546 *
2547 * If we are successful in aborting the command then
2548 * we're done here because we'll get the command returned
2549 * back separately.
2550 */
2551 if (isp_control(isp, ISPCTL_ABORT_CMD, xs) == 0) {
2552 return;
2553 }
2554
2555 /*
2556 * Note that after calling the above, the command may in
2557 * fact have been completed.
2558 */
2559 xs = isp_find_xs(isp, handle);
2560
2561 /*
2562 * If the command no longer exists, then we won't
2563 * be able to find the xs again with this handle.
2564 */
2565 if (xs == NULL) {
2566 return;
2567 }
2568
2569 /*
2570 * After this point, the command is really dead.
2571 */
2572 if (XS_XFRLEN(xs)) {
2573 ISP_DMAFREE(isp, xs, handle);
2574 }
2575 isp_destroy_handle(isp, handle);
2576 isp_prt(isp, ISP_LOGERR, "%s: timeout for handle 0x%x", __func__, handle);
2577 XS_SETERR(xs, CAM_CMD_TIMEOUT);
2578 isp_done(xs);
2579 } else {
2580 if (ohandle != ISP_HANDLE_FREE) {
2581 isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle 0x%x, recovered during interrupt", __func__, ohandle);
2582 } else {
2583 isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle already free", __func__);
2584 }
2585 }
2586 }
2587
2588 static void
isp_make_here(ispsoftc_t * isp,fcportdb_t * fcp,int chan,int tgt)2589 isp_make_here(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt)
2590 {
2591 union ccb *ccb;
2592 struct isp_fc *fc = ISP_FC_PC(isp, chan);
2593
2594 /*
2595 * Allocate a CCB, create a wildcard path for this target and schedule a rescan.
2596 */
2597 ccb = xpt_alloc_ccb_nowait();
2598 if (ccb == NULL) {
2599 isp_prt(isp, ISP_LOGWARN, "Chan %d unable to alloc CCB for rescan", chan);
2600 return;
2601 }
2602 if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(fc->sim),
2603 tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2604 isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
2605 xpt_free_ccb(ccb);
2606 return;
2607 }
2608 xpt_rescan(ccb);
2609 }
2610
2611 static void
isp_make_gone(ispsoftc_t * isp,fcportdb_t * fcp,int chan,int tgt)2612 isp_make_gone(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt)
2613 {
2614 struct cam_path *tp;
2615 struct isp_fc *fc = ISP_FC_PC(isp, chan);
2616
2617 if (xpt_create_path(&tp, NULL, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
2618 xpt_async(AC_LOST_DEVICE, tp, NULL);
2619 xpt_free_path(tp);
2620 }
2621 }
2622
2623 /*
2624 * Gone Device Timer Function- when we have decided that a device has gone
2625 * away, we wait a specific period of time prior to telling the OS it has
2626 * gone away.
2627 *
2628 * This timer function fires once a second and then scans the port database
2629 * for devices that are marked dead but still have a virtual target assigned.
2630 * We decrement a counter for that port database entry, and when it hits zero,
2631 * we tell the OS the device has gone away.
2632 */
2633 static void
isp_gdt(void * arg)2634 isp_gdt(void *arg)
2635 {
2636 struct isp_fc *fc = arg;
2637 taskqueue_enqueue(taskqueue_thread, &fc->gtask);
2638 }
2639
2640 static void
isp_gdt_task(void * arg,int pending)2641 isp_gdt_task(void *arg, int pending)
2642 {
2643 struct isp_fc *fc = arg;
2644 ispsoftc_t *isp = fc->isp;
2645 int chan = fc - isp->isp_osinfo.pc.fc;
2646 fcportdb_t *lp;
2647 struct ac_contract ac;
2648 struct ac_device_changed *adc;
2649 int dbidx, more_to_do = 0;
2650
2651 ISP_LOCK(isp);
2652 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GDT timer expired", chan);
2653 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2654 lp = &FCPARAM(isp, chan)->portdb[dbidx];
2655
2656 if (lp->state != FC_PORTDB_STATE_ZOMBIE) {
2657 continue;
2658 }
2659 if (lp->gone_timer != 0) {
2660 lp->gone_timer -= 1;
2661 more_to_do++;
2662 continue;
2663 }
2664 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, dbidx, lp->portid, "Gone Device Timeout");
2665 if (lp->is_target) {
2666 lp->is_target = 0;
2667 isp_make_gone(isp, lp, chan, dbidx);
2668 }
2669 if (lp->is_initiator) {
2670 lp->is_initiator = 0;
2671 ac.contract_number = AC_CONTRACT_DEV_CHG;
2672 adc = (struct ac_device_changed *) ac.contract_data;
2673 adc->wwpn = lp->port_wwn;
2674 adc->port = lp->portid;
2675 adc->target = dbidx;
2676 adc->arrived = 0;
2677 xpt_async(AC_CONTRACT, fc->path, &ac);
2678 }
2679 lp->state = FC_PORTDB_STATE_NIL;
2680 }
2681 if (fc->ready) {
2682 if (more_to_do) {
2683 callout_reset(&fc->gdt, hz, isp_gdt, fc);
2684 } else {
2685 callout_deactivate(&fc->gdt);
2686 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Stopping Gone Device Timer @ %lu", chan, (unsigned long) time_uptime);
2687 }
2688 }
2689 ISP_UNLOCK(isp);
2690 }
2691
2692 /*
2693 * When loop goes down we remember the time and freeze CAM command queue.
2694 * During some time period we are trying to reprobe the loop. But if we
2695 * fail, we tell the OS that devices have gone away and drop the freeze.
2696 *
2697 * We don't clear the devices out of our port database because, when loop
2698 * come back up, we have to do some actual cleanup with the chip at that
2699 * point (implicit PLOGO, e.g., to get the chip's port database state right).
2700 */
2701 static void
isp_loop_changed(ispsoftc_t * isp,int chan)2702 isp_loop_changed(ispsoftc_t *isp, int chan)
2703 {
2704 fcparam *fcp = FCPARAM(isp, chan);
2705 struct isp_fc *fc = ISP_FC_PC(isp, chan);
2706
2707 if (fc->loop_down_time)
2708 return;
2709 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop changed", chan);
2710 if (fcp->role & ISP_ROLE_INITIATOR)
2711 isp_freeze_loopdown(isp, chan);
2712 fc->loop_down_time = time_uptime;
2713 wakeup(fc);
2714 }
2715
2716 static void
isp_loop_up(ispsoftc_t * isp,int chan)2717 isp_loop_up(ispsoftc_t *isp, int chan)
2718 {
2719 struct isp_fc *fc = ISP_FC_PC(isp, chan);
2720
2721 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop is up", chan);
2722 fc->loop_seen_once = 1;
2723 fc->loop_down_time = 0;
2724 isp_unfreeze_loopdown(isp, chan);
2725 }
2726
2727 static void
isp_loop_dead(ispsoftc_t * isp,int chan)2728 isp_loop_dead(ispsoftc_t *isp, int chan)
2729 {
2730 fcparam *fcp = FCPARAM(isp, chan);
2731 struct isp_fc *fc = ISP_FC_PC(isp, chan);
2732 fcportdb_t *lp;
2733 struct ac_contract ac;
2734 struct ac_device_changed *adc;
2735 int dbidx, i;
2736
2737 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop is dead", chan);
2738
2739 /*
2740 * Notify to the OS all targets who we now consider have departed.
2741 */
2742 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2743 lp = &fcp->portdb[dbidx];
2744
2745 if (lp->state == FC_PORTDB_STATE_NIL)
2746 continue;
2747
2748 for (i = 0; i < isp->isp_maxcmds; i++) {
2749 struct ccb_scsiio *xs;
2750
2751 if (ISP_H2HT(isp->isp_xflist[i].handle) != ISP_HANDLE_INITIATOR) {
2752 continue;
2753 }
2754 if ((xs = isp->isp_xflist[i].cmd) == NULL) {
2755 continue;
2756 }
2757 if (dbidx != XS_TGT(xs)) {
2758 continue;
2759 }
2760 isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%jx orphaned by loop down timeout",
2761 isp->isp_xflist[i].handle, chan, XS_TGT(xs),
2762 (uintmax_t)XS_LUN(xs));
2763
2764 /*
2765 * Just like in isp_watchdog, abort the outstanding
2766 * command or immediately free its resources if it is
2767 * not active
2768 */
2769 if (isp_control(isp, ISPCTL_ABORT_CMD, xs) == 0) {
2770 continue;
2771 }
2772
2773 if (XS_XFRLEN(xs)) {
2774 ISP_DMAFREE(isp, xs, isp->isp_xflist[i].handle);
2775 }
2776 isp_destroy_handle(isp, isp->isp_xflist[i].handle);
2777 isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%jx could not be aborted and was destroyed",
2778 isp->isp_xflist[i].handle, chan, XS_TGT(xs),
2779 (uintmax_t)XS_LUN(xs));
2780 XS_SETERR(xs, HBA_BUSRESET);
2781 isp_done(xs);
2782 }
2783
2784 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, dbidx, lp->portid, "Loop Down Timeout");
2785 if (lp->is_target) {
2786 lp->is_target = 0;
2787 isp_make_gone(isp, lp, chan, dbidx);
2788 }
2789 if (lp->is_initiator) {
2790 lp->is_initiator = 0;
2791 ac.contract_number = AC_CONTRACT_DEV_CHG;
2792 adc = (struct ac_device_changed *) ac.contract_data;
2793 adc->wwpn = lp->port_wwn;
2794 adc->port = lp->portid;
2795 adc->target = dbidx;
2796 adc->arrived = 0;
2797 xpt_async(AC_CONTRACT, fc->path, &ac);
2798 }
2799 }
2800
2801 isp_unfreeze_loopdown(isp, chan);
2802 fc->loop_down_time = 0;
2803 }
2804
2805 static void
isp_kthread(void * arg)2806 isp_kthread(void *arg)
2807 {
2808 struct isp_fc *fc = arg;
2809 ispsoftc_t *isp = fc->isp;
2810 int chan = fc - isp->isp_osinfo.pc.fc;
2811 int slp = 0, d;
2812 int lb, lim;
2813
2814 ISP_LOCK(isp);
2815 while (isp->isp_osinfo.is_exiting == 0) {
2816 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0,
2817 "Chan %d Checking FC state", chan);
2818 lb = isp_fc_runstate(isp, chan, 250000);
2819 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0,
2820 "Chan %d FC got to %s state", chan,
2821 isp_fc_loop_statename(lb));
2822
2823 /*
2824 * Our action is different based upon whether we're supporting
2825 * Initiator mode or not. If we are, we might freeze the simq
2826 * when loop is down and set all sorts of different delays to
2827 * check again.
2828 *
2829 * If not, we simply just wait for loop to come up.
2830 */
2831 if (lb == LOOP_READY || lb < 0) {
2832 slp = 0;
2833 } else {
2834 /*
2835 * If we've never seen loop up and we've waited longer
2836 * than quickboot time, or we've seen loop up but we've
2837 * waited longer than loop_down_limit, give up and go
2838 * to sleep until loop comes up.
2839 */
2840 if (fc->loop_seen_once == 0)
2841 lim = isp_quickboot_time;
2842 else
2843 lim = fc->loop_down_limit;
2844 d = time_uptime - fc->loop_down_time;
2845 if (d >= lim)
2846 slp = 0;
2847 else if (d < 10)
2848 slp = 1;
2849 else if (d < 30)
2850 slp = 5;
2851 else if (d < 60)
2852 slp = 10;
2853 else if (d < 120)
2854 slp = 20;
2855 else
2856 slp = 30;
2857 }
2858
2859 if (slp == 0) {
2860 if (lb == LOOP_READY)
2861 isp_loop_up(isp, chan);
2862 else
2863 isp_loop_dead(isp, chan);
2864 }
2865
2866 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0,
2867 "Chan %d sleep for %d seconds", chan, slp);
2868 msleep(fc, &isp->isp_lock, PRIBIO, "ispf", slp * hz);
2869 }
2870 fc->num_threads -= 1;
2871 ISP_UNLOCK(isp);
2872 kthread_exit();
2873 }
2874
2875 #ifdef ISP_TARGET_MODE
2876 static void
isp_abort_atio(ispsoftc_t * isp,union ccb * ccb)2877 isp_abort_atio(ispsoftc_t *isp, union ccb *ccb)
2878 {
2879 atio_private_data_t *atp;
2880 union ccb *accb = ccb->cab.abort_ccb;
2881 struct ccb_hdr *sccb;
2882 tstate_t *tptr;
2883
2884 tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
2885 if (tptr != NULL) {
2886 /* Search for the ATIO among queueued. */
2887 SLIST_FOREACH(sccb, &tptr->atios, sim_links.sle) {
2888 if (sccb != &accb->ccb_h)
2889 continue;
2890 SLIST_REMOVE(&tptr->atios, sccb, ccb_hdr, sim_links.sle);
2891 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, sccb->path,
2892 "Abort FREE ATIO\n");
2893 accb->ccb_h.status = CAM_REQ_ABORTED;
2894 xpt_done(accb);
2895 ccb->ccb_h.status = CAM_REQ_CMP;
2896 return;
2897 }
2898 }
2899
2900 /* Search for the ATIO among running. */
2901 atp = isp_find_atpd(isp, XS_CHANNEL(accb), accb->atio.tag_id);
2902 if (atp != NULL) {
2903 /* Send TERMINATE to firmware. */
2904 if (!atp->dead && IS_24XX(isp)) {
2905 uint8_t storage[QENTRY_LEN];
2906 ct7_entry_t *cto = (ct7_entry_t *) storage;
2907
2908 ISP_MEMZERO(cto, sizeof (ct7_entry_t));
2909 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
2910 cto->ct_header.rqs_entry_count = 1;
2911 cto->ct_nphdl = atp->nphdl;
2912 cto->ct_rxid = atp->tag;
2913 cto->ct_iid_lo = atp->sid;
2914 cto->ct_iid_hi = atp->sid >> 16;
2915 cto->ct_oxid = atp->oxid;
2916 cto->ct_vpidx = XS_CHANNEL(accb);
2917 cto->ct_flags = CT7_NOACK|CT7_TERMINATE;
2918 isp_target_put_entry(isp, cto);
2919 }
2920 isp_put_atpd(isp, XS_CHANNEL(accb), atp);
2921 ccb->ccb_h.status = CAM_REQ_CMP;
2922 } else {
2923 ccb->ccb_h.status = CAM_UA_ABORT;
2924 }
2925 }
2926
2927 static void
isp_abort_inot(ispsoftc_t * isp,union ccb * ccb)2928 isp_abort_inot(ispsoftc_t *isp, union ccb *ccb)
2929 {
2930 inot_private_data_t *ntp;
2931 union ccb *accb = ccb->cab.abort_ccb;
2932 struct ccb_hdr *sccb;
2933 tstate_t *tptr;
2934
2935 tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
2936 if (tptr != NULL) {
2937 /* Search for the INOT among queueued. */
2938 SLIST_FOREACH(sccb, &tptr->inots, sim_links.sle) {
2939 if (sccb != &accb->ccb_h)
2940 continue;
2941 SLIST_REMOVE(&tptr->inots, sccb, ccb_hdr, sim_links.sle);
2942 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, sccb->path,
2943 "Abort FREE INOT\n");
2944 accb->ccb_h.status = CAM_REQ_ABORTED;
2945 xpt_done(accb);
2946 ccb->ccb_h.status = CAM_REQ_CMP;
2947 return;
2948 }
2949 }
2950
2951 /* Search for the INOT among running. */
2952 ntp = isp_find_ntpd(isp, XS_CHANNEL(accb), accb->cin1.tag_id, accb->cin1.seq_id);
2953 if (ntp != NULL) {
2954 if (ntp->nt.nt_need_ack) {
2955 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK,
2956 ntp->nt.nt_lreserved);
2957 }
2958 isp_put_ntpd(isp, XS_CHANNEL(accb), ntp);
2959 ccb->ccb_h.status = CAM_REQ_CMP;
2960 } else {
2961 ccb->ccb_h.status = CAM_UA_ABORT;
2962 return;
2963 }
2964 }
2965 #endif
2966
2967 static void
isp_action(struct cam_sim * sim,union ccb * ccb)2968 isp_action(struct cam_sim *sim, union ccb *ccb)
2969 {
2970 int bus, tgt, error;
2971 ispsoftc_t *isp;
2972 struct ccb_trans_settings *cts;
2973 sbintime_t ts;
2974
2975 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
2976
2977 isp = (ispsoftc_t *)cam_sim_softc(sim);
2978 ISP_ASSERT_LOCKED(isp);
2979 bus = cam_sim_bus(sim);
2980 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
2981 ISP_PCMD(ccb) = NULL;
2982
2983 switch (ccb->ccb_h.func_code) {
2984 case XPT_SCSI_IO: /* Execute the requested I/O operation */
2985 /*
2986 * Do a couple of preliminary checks...
2987 */
2988 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
2989 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
2990 ccb->ccb_h.status = CAM_REQ_INVALID;
2991 isp_done((struct ccb_scsiio *) ccb);
2992 break;
2993 }
2994 }
2995 ccb->csio.req_map = NULL;
2996 #ifdef DIAGNOSTIC
2997 if (ccb->ccb_h.target_id >= ISP_MAX_TARGETS(isp)) {
2998 xpt_print(ccb->ccb_h.path, "invalid target\n");
2999 ccb->ccb_h.status = CAM_PATH_INVALID;
3000 } else if (ISP_MAX_LUNS(isp) > 0 &&
3001 ccb->ccb_h.target_lun >= ISP_MAX_LUNS(isp)) {
3002 xpt_print(ccb->ccb_h.path, "invalid lun\n");
3003 ccb->ccb_h.status = CAM_PATH_INVALID;
3004 }
3005 if (ccb->ccb_h.status == CAM_PATH_INVALID) {
3006 xpt_done(ccb);
3007 break;
3008 }
3009 #endif
3010 ccb->csio.scsi_status = SCSI_STATUS_OK;
3011 if (isp_get_pcmd(isp, ccb)) {
3012 isp_prt(isp, ISP_LOGWARN, "out of PCMDs");
3013 cam_freeze_devq(ccb->ccb_h.path);
3014 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
3015 ccb->ccb_h.status = CAM_REQUEUE_REQ;
3016 xpt_done(ccb);
3017 break;
3018 }
3019 error = isp_start((XS_T *) ccb);
3020 switch (error) {
3021 case CMD_QUEUED:
3022 ccb->ccb_h.status |= CAM_SIM_QUEUED;
3023 if (ccb->ccb_h.timeout == CAM_TIME_INFINITY)
3024 break;
3025 /* Give firmware extra 10s to handle timeout. */
3026 ts = SBT_1MS * ccb->ccb_h.timeout + 10 * SBT_1S;
3027 callout_reset_sbt(&PISP_PCMD(ccb)->wdog, ts, 0,
3028 isp_watchdog, ccb, 0);
3029 break;
3030 case CMD_RQLATER:
3031 isp_prt(isp, ISP_LOGDEBUG0, "%d.%jx retry later",
3032 XS_TGT(ccb), (uintmax_t)XS_LUN(ccb));
3033 cam_freeze_devq(ccb->ccb_h.path);
3034 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
3035 ccb->ccb_h.status = CAM_REQUEUE_REQ;
3036 isp_free_pcmd(isp, ccb);
3037 xpt_done(ccb);
3038 break;
3039 case CMD_EAGAIN:
3040 isp_free_pcmd(isp, ccb);
3041 cam_freeze_devq(ccb->ccb_h.path);
3042 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0);
3043 ccb->ccb_h.status = CAM_REQUEUE_REQ;
3044 xpt_done(ccb);
3045 break;
3046 case CMD_COMPLETE:
3047 isp_done((struct ccb_scsiio *) ccb);
3048 break;
3049 default:
3050 isp_prt(isp, ISP_LOGERR, "What's this? 0x%x at %d in file %s", error, __LINE__, __FILE__);
3051 ccb->ccb_h.status = CAM_REQUEUE_REQ;
3052 isp_free_pcmd(isp, ccb);
3053 xpt_done(ccb);
3054 }
3055 break;
3056
3057 #ifdef ISP_TARGET_MODE
3058 case XPT_EN_LUN: /* Enable/Disable LUN as a target */
3059 if (ccb->cel.enable) {
3060 isp_enable_lun(isp, ccb);
3061 } else {
3062 isp_disable_lun(isp, ccb);
3063 }
3064 break;
3065 case XPT_IMMEDIATE_NOTIFY: /* Add Immediate Notify Resource */
3066 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */
3067 {
3068 tstate_t *tptr = get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
3069 if (tptr == NULL) {
3070 const char *str;
3071
3072 if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY)
3073 str = "XPT_IMMEDIATE_NOTIFY";
3074 else
3075 str = "XPT_ACCEPT_TARGET_IO";
3076 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path,
3077 "%s: no state pointer found for %s\n",
3078 __func__, str);
3079 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
3080 xpt_done(ccb);
3081 break;
3082 }
3083 ccb->ccb_h.spriv_field0 = 0;
3084 ccb->ccb_h.spriv_ptr1 = isp;
3085
3086 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
3087 ccb->atio.tag_id = 0;
3088 SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle);
3089 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path,
3090 "Put FREE ATIO\n");
3091 } else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
3092 ccb->cin1.seq_id = ccb->cin1.tag_id = 0;
3093 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
3094 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path,
3095 "Put FREE INOT\n");
3096 }
3097 ccb->ccb_h.status = CAM_REQ_INPROG;
3098 break;
3099 }
3100 case XPT_NOTIFY_ACKNOWLEDGE: /* notify ack */
3101 {
3102 inot_private_data_t *ntp;
3103
3104 /*
3105 * XXX: Because we cannot guarantee that the path information in the notify acknowledge ccb
3106 * XXX: matches that for the immediate notify, we have to *search* for the notify structure
3107 */
3108 /*
3109 * All the relevant path information is in the associated immediate notify
3110 */
3111 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] NOTIFY ACKNOWLEDGE for 0x%x seen\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id);
3112 ntp = isp_find_ntpd(isp, XS_CHANNEL(ccb), ccb->cna2.tag_id, ccb->cna2.seq_id);
3113 if (ntp == NULL) {
3114 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] XPT_NOTIFY_ACKNOWLEDGE of 0x%x cannot find ntp private data\n", __func__,
3115 ccb->cna2.tag_id, ccb->cna2.seq_id);
3116 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
3117 xpt_done(ccb);
3118 break;
3119 }
3120 if (isp_handle_platform_target_notify_ack(isp, &ntp->nt,
3121 (ccb->ccb_h.flags & CAM_SEND_STATUS) ? ccb->cna2.arg : 0)) {
3122 cam_freeze_devq(ccb->ccb_h.path);
3123 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
3124 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
3125 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
3126 break;
3127 }
3128 isp_put_ntpd(isp, XS_CHANNEL(ccb), ntp);
3129 ccb->ccb_h.status = CAM_REQ_CMP;
3130 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] calling xpt_done for tag 0x%x\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id);
3131 xpt_done(ccb);
3132 break;
3133 }
3134 case XPT_CONT_TARGET_IO:
3135 isp_target_start_ctio(isp, ccb, FROM_CAM);
3136 break;
3137 #endif
3138 case XPT_RESET_DEV: /* BDR the specified SCSI device */
3139 tgt = ccb->ccb_h.target_id;
3140 tgt |= (bus << 16);
3141
3142 error = isp_control(isp, ISPCTL_RESET_DEV, bus, tgt);
3143 if (error) {
3144 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
3145 } else {
3146 /*
3147 * If we have a FC device, reset the Command
3148 * Reference Number, because the target will expect
3149 * that we re-start the CRN at 1 after a reset.
3150 */
3151 if (IS_FC(isp))
3152 isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
3153
3154 ccb->ccb_h.status = CAM_REQ_CMP;
3155 }
3156 xpt_done(ccb);
3157 break;
3158 case XPT_ABORT: /* Abort the specified CCB */
3159 {
3160 union ccb *accb = ccb->cab.abort_ccb;
3161 switch (accb->ccb_h.func_code) {
3162 #ifdef ISP_TARGET_MODE
3163 case XPT_ACCEPT_TARGET_IO:
3164 isp_abort_atio(isp, ccb);
3165 break;
3166 case XPT_IMMEDIATE_NOTIFY:
3167 isp_abort_inot(isp, ccb);
3168 break;
3169 #endif
3170 case XPT_SCSI_IO:
3171 error = isp_control(isp, ISPCTL_ABORT_CMD, accb);
3172 if (error) {
3173 ccb->ccb_h.status = CAM_UA_ABORT;
3174 } else {
3175 ccb->ccb_h.status = CAM_REQ_CMP;
3176 }
3177 break;
3178 default:
3179 ccb->ccb_h.status = CAM_REQ_INVALID;
3180 break;
3181 }
3182 /*
3183 * This is not a queued CCB, so the caller expects it to be
3184 * complete when control is returned.
3185 */
3186 break;
3187 }
3188 #define IS_CURRENT_SETTINGS(c) (c->type == CTS_TYPE_CURRENT_SETTINGS)
3189 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */
3190 cts = &ccb->cts;
3191 if (!IS_CURRENT_SETTINGS(cts)) {
3192 ccb->ccb_h.status = CAM_REQ_INVALID;
3193 xpt_done(ccb);
3194 break;
3195 }
3196 tgt = cts->ccb_h.target_id;
3197 if (IS_SCSI(isp)) {
3198 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
3199 struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
3200 sdparam *sdp = SDPARAM(isp, bus);
3201 uint16_t *dptr;
3202
3203 if (spi->valid == 0 && scsi->valid == 0) {
3204 ccb->ccb_h.status = CAM_REQ_CMP;
3205 xpt_done(ccb);
3206 break;
3207 }
3208
3209 /*
3210 * We always update (internally) from goal_flags
3211 * so any request to change settings just gets
3212 * vectored to that location.
3213 */
3214 dptr = &sdp->isp_devparam[tgt].goal_flags;
3215
3216 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
3217 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
3218 *dptr |= DPARM_DISC;
3219 else
3220 *dptr &= ~DPARM_DISC;
3221 }
3222
3223 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
3224 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
3225 *dptr |= DPARM_TQING;
3226 else
3227 *dptr &= ~DPARM_TQING;
3228 }
3229
3230 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
3231 if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
3232 *dptr |= DPARM_WIDE;
3233 else
3234 *dptr &= ~DPARM_WIDE;
3235 }
3236
3237 /*
3238 * XXX: FIX ME
3239 */
3240 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) && (spi->valid & CTS_SPI_VALID_SYNC_RATE) && (spi->sync_period && spi->sync_offset)) {
3241 *dptr |= DPARM_SYNC;
3242 /*
3243 * XXX: CHECK FOR LEGALITY
3244 */
3245 sdp->isp_devparam[tgt].goal_period = spi->sync_period;
3246 sdp->isp_devparam[tgt].goal_offset = spi->sync_offset;
3247 } else {
3248 *dptr &= ~DPARM_SYNC;
3249 }
3250 isp_prt(isp, ISP_LOGDEBUG0, "SET (%d.%d.%jx) to flags %x off %x per %x", bus, tgt, (uintmax_t)cts->ccb_h.target_lun, sdp->isp_devparam[tgt].goal_flags,
3251 sdp->isp_devparam[tgt].goal_offset, sdp->isp_devparam[tgt].goal_period);
3252 sdp->isp_devparam[tgt].dev_update = 1;
3253 sdp->update = 1;
3254 }
3255 ccb->ccb_h.status = CAM_REQ_CMP;
3256 xpt_done(ccb);
3257 break;
3258 case XPT_GET_TRAN_SETTINGS:
3259 cts = &ccb->cts;
3260 tgt = cts->ccb_h.target_id;
3261 if (IS_FC(isp)) {
3262 fcparam *fcp = FCPARAM(isp, bus);
3263 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
3264 struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
3265
3266 cts->protocol = PROTO_SCSI;
3267 cts->protocol_version = SCSI_REV_2;
3268 cts->transport = XPORT_FC;
3269 cts->transport_version = 0;
3270
3271 scsi->valid = CTS_SCSI_VALID_TQ;
3272 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
3273 fc->valid = CTS_FC_VALID_SPEED;
3274 fc->bitrate = 100000;
3275 fc->bitrate *= fcp->isp_gbspeed;
3276 if (tgt < MAX_FC_TARG) {
3277 fcportdb_t *lp = &fcp->portdb[tgt];
3278 fc->wwnn = lp->node_wwn;
3279 fc->wwpn = lp->port_wwn;
3280 fc->port = lp->portid;
3281 fc->valid |= CTS_FC_VALID_WWNN | CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT;
3282 }
3283 } else {
3284 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
3285 struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
3286 sdparam *sdp = SDPARAM(isp, bus);
3287 uint16_t dval, pval, oval;
3288
3289 if (IS_CURRENT_SETTINGS(cts)) {
3290 sdp->isp_devparam[tgt].dev_refresh = 1;
3291 sdp->update = 1;
3292 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus);
3293 dval = sdp->isp_devparam[tgt].actv_flags;
3294 oval = sdp->isp_devparam[tgt].actv_offset;
3295 pval = sdp->isp_devparam[tgt].actv_period;
3296 } else {
3297 dval = sdp->isp_devparam[tgt].nvrm_flags;
3298 oval = sdp->isp_devparam[tgt].nvrm_offset;
3299 pval = sdp->isp_devparam[tgt].nvrm_period;
3300 }
3301
3302 cts->protocol = PROTO_SCSI;
3303 cts->protocol_version = SCSI_REV_2;
3304 cts->transport = XPORT_SPI;
3305 cts->transport_version = 2;
3306
3307 spi->valid = 0;
3308 scsi->valid = 0;
3309 spi->flags = 0;
3310 scsi->flags = 0;
3311 if (dval & DPARM_DISC) {
3312 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3313 }
3314 if ((dval & DPARM_SYNC) && oval && pval) {
3315 spi->sync_offset = oval;
3316 spi->sync_period = pval;
3317 } else {
3318 spi->sync_offset = 0;
3319 spi->sync_period = 0;
3320 }
3321 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3322 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3323 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3324 if (dval & DPARM_WIDE) {
3325 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
3326 } else {
3327 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
3328 }
3329 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
3330 scsi->valid = CTS_SCSI_VALID_TQ;
3331 if (dval & DPARM_TQING) {
3332 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3333 }
3334 spi->valid |= CTS_SPI_VALID_DISC;
3335 }
3336 isp_prt(isp, ISP_LOGDEBUG0, "GET %s (%d.%d.%jx) to flags %x off %x per %x", IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
3337 bus, tgt, (uintmax_t)cts->ccb_h.target_lun, dval, oval, pval);
3338 }
3339 ccb->ccb_h.status = CAM_REQ_CMP;
3340 xpt_done(ccb);
3341 break;
3342
3343 case XPT_CALC_GEOMETRY:
3344 cam_calc_geometry(&ccb->ccg, 1);
3345 xpt_done(ccb);
3346 break;
3347
3348 case XPT_RESET_BUS: /* Reset the specified bus */
3349 error = isp_control(isp, ISPCTL_RESET_BUS, bus);
3350 if (error) {
3351 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
3352 xpt_done(ccb);
3353 break;
3354 }
3355 if (bootverbose) {
3356 xpt_print(ccb->ccb_h.path, "reset bus on channel %d\n", bus);
3357 }
3358 if (IS_FC(isp)) {
3359 xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, 0);
3360 } else {
3361 xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, 0);
3362 }
3363 ccb->ccb_h.status = CAM_REQ_CMP;
3364 xpt_done(ccb);
3365 break;
3366
3367 case XPT_TERM_IO: /* Terminate the I/O process */
3368 ccb->ccb_h.status = CAM_REQ_INVALID;
3369 xpt_done(ccb);
3370 break;
3371
3372 case XPT_SET_SIM_KNOB: /* Set SIM knobs */
3373 {
3374 struct ccb_sim_knob *kp = &ccb->knob;
3375 fcparam *fcp;
3376
3377 if (!IS_FC(isp)) {
3378 ccb->ccb_h.status = CAM_REQ_INVALID;
3379 xpt_done(ccb);
3380 break;
3381 }
3382
3383 fcp = FCPARAM(isp, bus);
3384
3385 if (kp->xport_specific.fc.valid & KNOB_VALID_ADDRESS) {
3386 fcp->isp_wwnn = ISP_FC_PC(isp, bus)->def_wwnn = kp->xport_specific.fc.wwnn;
3387 fcp->isp_wwpn = ISP_FC_PC(isp, bus)->def_wwpn = kp->xport_specific.fc.wwpn;
3388 isp_prt(isp, ISP_LOGALL, "Setting Channel %d wwns to 0x%jx 0x%jx", bus, fcp->isp_wwnn, fcp->isp_wwpn);
3389 }
3390 ccb->ccb_h.status = CAM_REQ_CMP;
3391 if (kp->xport_specific.fc.valid & KNOB_VALID_ROLE) {
3392 int rchange = 0;
3393 int newrole = 0;
3394
3395 switch (kp->xport_specific.fc.role) {
3396 case KNOB_ROLE_NONE:
3397 if (fcp->role != ISP_ROLE_NONE) {
3398 rchange = 1;
3399 newrole = ISP_ROLE_NONE;
3400 }
3401 break;
3402 case KNOB_ROLE_TARGET:
3403 if (fcp->role != ISP_ROLE_TARGET) {
3404 rchange = 1;
3405 newrole = ISP_ROLE_TARGET;
3406 }
3407 break;
3408 case KNOB_ROLE_INITIATOR:
3409 if (fcp->role != ISP_ROLE_INITIATOR) {
3410 rchange = 1;
3411 newrole = ISP_ROLE_INITIATOR;
3412 }
3413 break;
3414 case KNOB_ROLE_BOTH:
3415 if (fcp->role != ISP_ROLE_BOTH) {
3416 rchange = 1;
3417 newrole = ISP_ROLE_BOTH;
3418 }
3419 break;
3420 }
3421 if (rchange) {
3422 ISP_PATH_PRT(isp, ISP_LOGCONFIG, ccb->ccb_h.path, "changing role on from %d to %d\n", fcp->role, newrole);
3423 if (isp_control(isp, ISPCTL_CHANGE_ROLE,
3424 bus, newrole) != 0) {
3425 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
3426 xpt_done(ccb);
3427 break;
3428 }
3429 }
3430 }
3431 xpt_done(ccb);
3432 break;
3433 }
3434 case XPT_GET_SIM_KNOB_OLD: /* Get SIM knobs -- compat value */
3435 case XPT_GET_SIM_KNOB: /* Get SIM knobs */
3436 {
3437 struct ccb_sim_knob *kp = &ccb->knob;
3438
3439 if (IS_FC(isp)) {
3440 fcparam *fcp;
3441
3442 fcp = FCPARAM(isp, bus);
3443
3444 kp->xport_specific.fc.wwnn = fcp->isp_wwnn;
3445 kp->xport_specific.fc.wwpn = fcp->isp_wwpn;
3446 switch (fcp->role) {
3447 case ISP_ROLE_NONE:
3448 kp->xport_specific.fc.role = KNOB_ROLE_NONE;
3449 break;
3450 case ISP_ROLE_TARGET:
3451 kp->xport_specific.fc.role = KNOB_ROLE_TARGET;
3452 break;
3453 case ISP_ROLE_INITIATOR:
3454 kp->xport_specific.fc.role = KNOB_ROLE_INITIATOR;
3455 break;
3456 case ISP_ROLE_BOTH:
3457 kp->xport_specific.fc.role = KNOB_ROLE_BOTH;
3458 break;
3459 }
3460 kp->xport_specific.fc.valid = KNOB_VALID_ADDRESS | KNOB_VALID_ROLE;
3461 ccb->ccb_h.status = CAM_REQ_CMP;
3462 } else {
3463 ccb->ccb_h.status = CAM_REQ_INVALID;
3464 }
3465 xpt_done(ccb);
3466 break;
3467 }
3468 case XPT_PATH_INQ: /* Path routing inquiry */
3469 {
3470 struct ccb_pathinq *cpi = &ccb->cpi;
3471
3472 cpi->version_num = 1;
3473 #ifdef ISP_TARGET_MODE
3474 if (IS_FC(isp) && ISP_CAP_TMODE(isp) && ISP_CAP_SCCFW(isp))
3475 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
3476 else
3477 #endif
3478 cpi->target_sprt = 0;
3479 cpi->hba_eng_cnt = 0;
3480 cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
3481 cpi->max_lun = ISP_MAX_LUNS(isp) == 0 ?
3482 255 : ISP_MAX_LUNS(isp) - 1;
3483 cpi->bus_id = cam_sim_bus(sim);
3484 if (sizeof (bus_size_t) > 4)
3485 cpi->maxio = (ISP_NSEG64_MAX - 1) * PAGE_SIZE;
3486 else
3487 cpi->maxio = (ISP_NSEG_MAX - 1) * PAGE_SIZE;
3488
3489 if (IS_FC(isp)) {
3490 fcparam *fcp = FCPARAM(isp, bus);
3491
3492 cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED;
3493 cpi->hba_misc |= PIM_EXTLUNS | PIM_NOSCAN;
3494
3495 /*
3496 * Because our loop ID can shift from time to time,
3497 * make our initiator ID out of range of our bus.
3498 */
3499 cpi->initiator_id = cpi->max_target + 1;
3500
3501 /*
3502 * Set base transfer capabilities for Fibre Channel, for this HBA.
3503 */
3504 if (IS_25XX(isp)) {
3505 cpi->base_transfer_speed = 8000000;
3506 } else if (IS_24XX(isp)) {
3507 cpi->base_transfer_speed = 4000000;
3508 } else if (IS_23XX(isp)) {
3509 cpi->base_transfer_speed = 2000000;
3510 } else {
3511 cpi->base_transfer_speed = 1000000;
3512 }
3513 cpi->hba_inquiry = PI_TAG_ABLE;
3514 cpi->transport = XPORT_FC;
3515 cpi->transport_version = 0;
3516 cpi->xport_specific.fc.wwnn = fcp->isp_wwnn;
3517 cpi->xport_specific.fc.wwpn = fcp->isp_wwpn;
3518 cpi->xport_specific.fc.port = fcp->isp_portid;
3519 cpi->xport_specific.fc.bitrate = fcp->isp_gbspeed * 1000;
3520 } else {
3521 sdparam *sdp = SDPARAM(isp, bus);
3522 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
3523 cpi->hba_misc = PIM_UNMAPPED;
3524 cpi->initiator_id = sdp->isp_initiator_id;
3525 cpi->base_transfer_speed = 3300;
3526 cpi->transport = XPORT_SPI;
3527 cpi->transport_version = 2;
3528 }
3529 cpi->protocol = PROTO_SCSI;
3530 cpi->protocol_version = SCSI_REV_2;
3531 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
3532 strlcpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
3533 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
3534 cpi->unit_number = cam_sim_unit(sim);
3535 cpi->ccb_h.status = CAM_REQ_CMP;
3536 xpt_done(ccb);
3537 break;
3538 }
3539 default:
3540 ccb->ccb_h.status = CAM_REQ_INVALID;
3541 xpt_done(ccb);
3542 break;
3543 }
3544 }
3545
3546 void
isp_done(XS_T * sccb)3547 isp_done(XS_T *sccb)
3548 {
3549 ispsoftc_t *isp = XS_ISP(sccb);
3550 uint32_t status;
3551
3552 if (XS_NOERR(sccb))
3553 XS_SETERR(sccb, CAM_REQ_CMP);
3554
3555 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && (sccb->scsi_status != SCSI_STATUS_OK)) {
3556 sccb->ccb_h.status &= ~CAM_STATUS_MASK;
3557 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
3558 sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
3559 } else {
3560 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
3561 }
3562 }
3563
3564 sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3565 status = sccb->ccb_h.status & CAM_STATUS_MASK;
3566 if (status != CAM_REQ_CMP &&
3567 (sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
3568 sccb->ccb_h.status |= CAM_DEV_QFRZN;
3569 xpt_freeze_devq(sccb->ccb_h.path, 1);
3570 }
3571
3572 if (ISP_PCMD(sccb)) {
3573 if (callout_active(&PISP_PCMD(sccb)->wdog))
3574 callout_stop(&PISP_PCMD(sccb)->wdog);
3575 isp_free_pcmd(isp, (union ccb *) sccb);
3576 }
3577 xpt_done((union ccb *) sccb);
3578 }
3579
3580 void
isp_async(ispsoftc_t * isp,ispasync_t cmd,...)3581 isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
3582 {
3583 int bus;
3584 static const char prom[] = "Chan %d [%d] WWPN 0x%16jx PortID 0x%06x handle 0x%x %s %s";
3585 char buf[64];
3586 char *msg = NULL;
3587 target_id_t tgt = 0;
3588 fcportdb_t *lp;
3589 struct isp_fc *fc;
3590 struct cam_path *tmppath;
3591 struct ac_contract ac;
3592 struct ac_device_changed *adc;
3593 va_list ap;
3594
3595 switch (cmd) {
3596 case ISPASYNC_NEW_TGT_PARAMS:
3597 {
3598 struct ccb_trans_settings_scsi *scsi;
3599 struct ccb_trans_settings_spi *spi;
3600 int flags, tgt;
3601 sdparam *sdp;
3602 struct ccb_trans_settings cts;
3603
3604 memset(&cts, 0, sizeof (struct ccb_trans_settings));
3605
3606 va_start(ap, cmd);
3607 bus = va_arg(ap, int);
3608 tgt = va_arg(ap, int);
3609 va_end(ap);
3610 sdp = SDPARAM(isp, bus);
3611
3612 if (xpt_create_path(&tmppath, NULL, cam_sim_path(ISP_SPI_PC(isp, bus)->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
3613 isp_prt(isp, ISP_LOGWARN, "isp_async cannot make temp path for %d.%d", tgt, bus);
3614 break;
3615 }
3616 flags = sdp->isp_devparam[tgt].actv_flags;
3617 cts.type = CTS_TYPE_CURRENT_SETTINGS;
3618 cts.protocol = PROTO_SCSI;
3619 cts.transport = XPORT_SPI;
3620
3621 scsi = &cts.proto_specific.scsi;
3622 spi = &cts.xport_specific.spi;
3623
3624 if (flags & DPARM_TQING) {
3625 scsi->valid |= CTS_SCSI_VALID_TQ;
3626 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3627 }
3628
3629 if (flags & DPARM_DISC) {
3630 spi->valid |= CTS_SPI_VALID_DISC;
3631 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3632 }
3633 spi->flags |= CTS_SPI_VALID_BUS_WIDTH;
3634 if (flags & DPARM_WIDE) {
3635 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
3636 } else {
3637 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
3638 }
3639 if (flags & DPARM_SYNC) {
3640 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3641 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3642 spi->sync_period = sdp->isp_devparam[tgt].actv_period;
3643 spi->sync_offset = sdp->isp_devparam[tgt].actv_offset;
3644 }
3645 isp_prt(isp, ISP_LOGDEBUG2, "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x", bus, tgt, sdp->isp_devparam[tgt].actv_period, sdp->isp_devparam[tgt].actv_offset, flags);
3646 xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
3647 xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
3648 xpt_free_path(tmppath);
3649 break;
3650 }
3651 case ISPASYNC_BUS_RESET:
3652 {
3653 va_start(ap, cmd);
3654 bus = va_arg(ap, int);
3655 va_end(ap);
3656 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected", bus);
3657 if (IS_FC(isp)) {
3658 xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, NULL);
3659 } else {
3660 xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, NULL);
3661 }
3662 break;
3663 }
3664 case ISPASYNC_LOOP_RESET:
3665 {
3666 uint16_t lipp;
3667 fcparam *fcp;
3668 va_start(ap, cmd);
3669 bus = va_arg(ap, int);
3670 va_end(ap);
3671
3672 lipp = ISP_READ(isp, OUTMAILBOX1);
3673 fcp = FCPARAM(isp, bus);
3674
3675 isp_prt(isp, ISP_LOGINFO, "Chan %d LOOP Reset, LIP primitive %x", bus, lipp);
3676 /*
3677 * Per FCP-4, a Reset LIP should result in a CRN reset. Other
3678 * LIPs and loop up/down events should never reset the CRN. For
3679 * an as of yet unknown reason, 24xx series cards (and
3680 * potentially others) can interrupt with a LIP Reset status
3681 * when no LIP reset came down the wire. Additionally, the LIP
3682 * primitive accompanying this status would not be a valid LIP
3683 * Reset primitive, but some variation of an invalid AL_PA
3684 * LIP. As a result, we have to verify the AL_PD in the LIP
3685 * addresses our port before blindly resetting.
3686 */
3687 if (FCP_IS_DEST_ALPD(fcp, (lipp & 0x00FF)))
3688 isp_fcp_reset_crn(isp, bus, /*tgt*/0, /*tgt_set*/ 0);
3689 isp_loop_changed(isp, bus);
3690 break;
3691 }
3692 case ISPASYNC_LIP:
3693 if (msg == NULL)
3694 msg = "LIP Received";
3695 /* FALLTHROUGH */
3696 case ISPASYNC_LOOP_DOWN:
3697 if (msg == NULL)
3698 msg = "LOOP Down";
3699 /* FALLTHROUGH */
3700 case ISPASYNC_LOOP_UP:
3701 if (msg == NULL)
3702 msg = "LOOP Up";
3703 va_start(ap, cmd);
3704 bus = va_arg(ap, int);
3705 va_end(ap);
3706 isp_loop_changed(isp, bus);
3707 isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg);
3708 break;
3709 case ISPASYNC_DEV_ARRIVED:
3710 va_start(ap, cmd);
3711 bus = va_arg(ap, int);
3712 lp = va_arg(ap, fcportdb_t *);
3713 va_end(ap);
3714 fc = ISP_FC_PC(isp, bus);
3715 tgt = FC_PORTDB_TGT(isp, bus, lp);
3716 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
3717 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "arrived");
3718 if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) &&
3719 (lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) {
3720 lp->is_target = 1;
3721 isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
3722 isp_make_here(isp, lp, bus, tgt);
3723 }
3724 if ((FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) &&
3725 (lp->prli_word3 & PRLI_WD3_INITIATOR_FUNCTION)) {
3726 lp->is_initiator = 1;
3727 ac.contract_number = AC_CONTRACT_DEV_CHG;
3728 adc = (struct ac_device_changed *) ac.contract_data;
3729 adc->wwpn = lp->port_wwn;
3730 adc->port = lp->portid;
3731 adc->target = tgt;
3732 adc->arrived = 1;
3733 xpt_async(AC_CONTRACT, fc->path, &ac);
3734 }
3735 break;
3736 case ISPASYNC_DEV_CHANGED:
3737 case ISPASYNC_DEV_STAYED:
3738 {
3739 int crn_reset_done;
3740
3741 crn_reset_done = 0;
3742 va_start(ap, cmd);
3743 bus = va_arg(ap, int);
3744 lp = va_arg(ap, fcportdb_t *);
3745 va_end(ap);
3746 fc = ISP_FC_PC(isp, bus);
3747 tgt = FC_PORTDB_TGT(isp, bus, lp);
3748 isp_gen_role_str(buf, sizeof (buf), lp->new_prli_word3);
3749 if (cmd == ISPASYNC_DEV_CHANGED)
3750 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->new_portid, lp->handle, buf, "changed");
3751 else
3752 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "stayed");
3753
3754 if (lp->is_target !=
3755 ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) &&
3756 (lp->new_prli_word3 & PRLI_WD3_TARGET_FUNCTION))) {
3757 lp->is_target = !lp->is_target;
3758 if (lp->is_target) {
3759 if (cmd == ISPASYNC_DEV_CHANGED) {
3760 isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
3761 crn_reset_done = 1;
3762 }
3763 isp_make_here(isp, lp, bus, tgt);
3764 } else {
3765 isp_make_gone(isp, lp, bus, tgt);
3766 if (cmd == ISPASYNC_DEV_CHANGED) {
3767 isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
3768 crn_reset_done = 1;
3769 }
3770 }
3771 }
3772 if (lp->is_initiator !=
3773 ((FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) &&
3774 (lp->new_prli_word3 & PRLI_WD3_INITIATOR_FUNCTION))) {
3775 lp->is_initiator = !lp->is_initiator;
3776 ac.contract_number = AC_CONTRACT_DEV_CHG;
3777 adc = (struct ac_device_changed *) ac.contract_data;
3778 adc->wwpn = lp->port_wwn;
3779 adc->port = lp->portid;
3780 adc->target = tgt;
3781 adc->arrived = lp->is_initiator;
3782 xpt_async(AC_CONTRACT, fc->path, &ac);
3783 }
3784
3785 if ((cmd == ISPASYNC_DEV_CHANGED) &&
3786 (crn_reset_done == 0))
3787 isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
3788
3789 break;
3790 }
3791 case ISPASYNC_DEV_GONE:
3792 va_start(ap, cmd);
3793 bus = va_arg(ap, int);
3794 lp = va_arg(ap, fcportdb_t *);
3795 va_end(ap);
3796 fc = ISP_FC_PC(isp, bus);
3797 tgt = FC_PORTDB_TGT(isp, bus, lp);
3798 /*
3799 * If this has a virtual target or initiator set the isp_gdt
3800 * timer running on it to delay its departure.
3801 */
3802 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
3803 if (lp->is_target || lp->is_initiator) {
3804 lp->state = FC_PORTDB_STATE_ZOMBIE;
3805 lp->gone_timer = fc->gone_device_time;
3806 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "gone zombie");
3807 if (fc->ready && !callout_active(&fc->gdt)) {
3808 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Starting Gone Device Timer with %u seconds time now %lu", bus, lp->gone_timer, (unsigned long)time_uptime);
3809 callout_reset(&fc->gdt, hz, isp_gdt, fc);
3810 }
3811 break;
3812 }
3813 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "gone");
3814 break;
3815 case ISPASYNC_CHANGE_NOTIFY:
3816 {
3817 char *msg;
3818 int evt, nphdl, nlstate, portid, reason;
3819
3820 va_start(ap, cmd);
3821 bus = va_arg(ap, int);
3822 evt = va_arg(ap, int);
3823 if (evt == ISPASYNC_CHANGE_PDB) {
3824 nphdl = va_arg(ap, int);
3825 nlstate = va_arg(ap, int);
3826 reason = va_arg(ap, int);
3827 } else if (evt == ISPASYNC_CHANGE_SNS) {
3828 portid = va_arg(ap, int);
3829 } else {
3830 nphdl = NIL_HANDLE;
3831 nlstate = reason = 0;
3832 }
3833 va_end(ap);
3834
3835 if (evt == ISPASYNC_CHANGE_PDB) {
3836 int tgt_set = 0;
3837 msg = "Port Database Changed";
3838 isp_prt(isp, ISP_LOGINFO,
3839 "Chan %d %s (nphdl 0x%x state 0x%x reason 0x%x)",
3840 bus, msg, nphdl, nlstate, reason);
3841 /*
3842 * Port database syncs are not sufficient for
3843 * determining that logins or logouts are done on the
3844 * loop, but this information is directly available from
3845 * the reason code from the incoming mbox. We must reset
3846 * the fcp crn on these events according to FCP-4
3847 */
3848 switch (reason) {
3849 case PDB24XX_AE_IMPL_LOGO_1:
3850 case PDB24XX_AE_IMPL_LOGO_2:
3851 case PDB24XX_AE_IMPL_LOGO_3:
3852 case PDB24XX_AE_PLOGI_RCVD:
3853 case PDB24XX_AE_PRLI_RCVD:
3854 case PDB24XX_AE_PRLO_RCVD:
3855 case PDB24XX_AE_LOGO_RCVD:
3856 case PDB24XX_AE_PLOGI_DONE:
3857 case PDB24XX_AE_PRLI_DONE:
3858 /*
3859 * If the event is not global, twiddle tgt and
3860 * tgt_set to nominate only the target
3861 * associated with the nphdl.
3862 */
3863 if (nphdl != PDB24XX_AE_GLOBAL) {
3864 /* Break if we don't yet have the pdb */
3865 if (!isp_find_pdb_by_handle(isp, bus, nphdl, &lp))
3866 break;
3867 tgt = FC_PORTDB_TGT(isp, bus, lp);
3868 tgt_set = 1;
3869 }
3870 isp_fcp_reset_crn(isp, bus, tgt, tgt_set);
3871 break;
3872 default:
3873 break; /* NOP */
3874 }
3875 } else if (evt == ISPASYNC_CHANGE_SNS) {
3876 msg = "Name Server Database Changed";
3877 isp_prt(isp, ISP_LOGINFO, "Chan %d %s (PortID 0x%06x)",
3878 bus, msg, portid);
3879 } else {
3880 msg = "Other Change Notify";
3881 isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg);
3882 }
3883 isp_loop_changed(isp, bus);
3884 break;
3885 }
3886 #ifdef ISP_TARGET_MODE
3887 case ISPASYNC_TARGET_NOTIFY:
3888 {
3889 isp_notify_t *notify;
3890 va_start(ap, cmd);
3891 notify = va_arg(ap, isp_notify_t *);
3892 va_end(ap);
3893 switch (notify->nt_ncode) {
3894 case NT_ABORT_TASK:
3895 case NT_ABORT_TASK_SET:
3896 case NT_CLEAR_ACA:
3897 case NT_CLEAR_TASK_SET:
3898 case NT_LUN_RESET:
3899 case NT_TARGET_RESET:
3900 case NT_QUERY_TASK_SET:
3901 case NT_QUERY_ASYNC_EVENT:
3902 /*
3903 * These are task management functions.
3904 */
3905 isp_handle_platform_target_tmf(isp, notify);
3906 break;
3907 case NT_BUS_RESET:
3908 case NT_LIP_RESET:
3909 case NT_LINK_UP:
3910 case NT_LINK_DOWN:
3911 case NT_HBA_RESET:
3912 /*
3913 * No action need be taken here.
3914 */
3915 break;
3916 case NT_GLOBAL_LOGOUT:
3917 case NT_LOGOUT:
3918 /*
3919 * This is device arrival/departure notification
3920 */
3921 isp_handle_platform_target_notify_ack(isp, notify, 0);
3922 break;
3923 case NT_SRR:
3924 isp_handle_platform_srr(isp, notify);
3925 break;
3926 default:
3927 isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode);
3928 isp_handle_platform_target_notify_ack(isp, notify, 0);
3929 break;
3930 }
3931 break;
3932 }
3933 case ISPASYNC_TARGET_NOTIFY_ACK:
3934 {
3935 void *inot;
3936 va_start(ap, cmd);
3937 inot = va_arg(ap, void *);
3938 va_end(ap);
3939 if (isp_notify_ack(isp, inot)) {
3940 isp_tna_t *tp = malloc(sizeof (*tp), M_DEVBUF, M_NOWAIT);
3941 if (tp) {
3942 tp->isp = isp;
3943 memcpy(tp->data, inot, sizeof (tp->data));
3944 tp->not = tp->data;
3945 callout_init_mtx(&tp->timer, &isp->isp_lock, 0);
3946 callout_reset(&tp->timer, 5,
3947 isp_refire_notify_ack, tp);
3948 } else {
3949 isp_prt(isp, ISP_LOGERR, "you lose- cannot allocate a notify refire");
3950 }
3951 }
3952 break;
3953 }
3954 case ISPASYNC_TARGET_ACTION:
3955 {
3956 isphdr_t *hp;
3957
3958 va_start(ap, cmd);
3959 hp = va_arg(ap, isphdr_t *);
3960 va_end(ap);
3961 switch (hp->rqs_entry_type) {
3962 case RQSTYPE_ATIO:
3963 isp_handle_platform_atio7(isp, (at7_entry_t *) hp);
3964 break;
3965 case RQSTYPE_ATIO2:
3966 isp_handle_platform_atio2(isp, (at2_entry_t *) hp);
3967 break;
3968 case RQSTYPE_CTIO7:
3969 case RQSTYPE_CTIO3:
3970 case RQSTYPE_CTIO2:
3971 case RQSTYPE_CTIO:
3972 isp_handle_platform_ctio(isp, hp);
3973 break;
3974 default:
3975 isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x",
3976 __func__, hp->rqs_entry_type);
3977 break;
3978 }
3979 break;
3980 }
3981 #endif
3982 case ISPASYNC_FW_CRASH:
3983 {
3984 uint16_t mbox1, mbox6;
3985 mbox1 = ISP_READ(isp, OUTMAILBOX1);
3986 if (IS_DUALBUS(isp)) {
3987 mbox6 = ISP_READ(isp, OUTMAILBOX6);
3988 } else {
3989 mbox6 = 0;
3990 }
3991 isp_prt(isp, ISP_LOGERR, "Internal Firmware Error on bus %d @ RISC Address 0x%x", mbox6, mbox1);
3992 #if 0
3993 mbox1 = isp->isp_osinfo.mbox_sleep_ok;
3994 isp->isp_osinfo.mbox_sleep_ok = 0;
3995 isp_reinit(isp, 1);
3996 isp->isp_osinfo.mbox_sleep_ok = mbox1;
3997 isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
3998 #endif
3999 break;
4000 }
4001 default:
4002 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
4003 break;
4004 }
4005 }
4006
4007 uint64_t
isp_default_wwn(ispsoftc_t * isp,int chan,int isactive,int iswwnn)4008 isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn)
4009 {
4010 uint64_t seed;
4011 struct isp_fc *fc = ISP_FC_PC(isp, chan);
4012
4013 /* First try to use explicitly configured WWNs. */
4014 seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
4015 if (seed)
4016 return (seed);
4017
4018 /* Otherwise try to use WWNs from NVRAM. */
4019 if (isactive) {
4020 seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram :
4021 FCPARAM(isp, chan)->isp_wwpn_nvram;
4022 if (seed)
4023 return (seed);
4024 }
4025
4026 /* If still no WWNs, try to steal them from the first channel. */
4027 if (chan > 0) {
4028 seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn :
4029 ISP_FC_PC(isp, 0)->def_wwpn;
4030 if (seed == 0) {
4031 seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram :
4032 FCPARAM(isp, 0)->isp_wwpn_nvram;
4033 }
4034 }
4035
4036 /* If still nothing -- improvise. */
4037 if (seed == 0) {
4038 seed = 0x400000007F000000ull + device_get_unit(isp->isp_dev);
4039 if (!iswwnn)
4040 seed ^= 0x0100000000000000ULL;
4041 }
4042
4043 /* For additional channels we have to improvise even more. */
4044 if (!iswwnn && chan > 0) {
4045 /*
4046 * We'll stick our channel number plus one first into bits
4047 * 57..59 and thence into bits 52..55 which allows for 8 bits
4048 * of channel which is enough for our maximum of 255 channels.
4049 */
4050 seed ^= 0x0100000000000000ULL;
4051 seed ^= ((uint64_t) (chan + 1) & 0xf) << 56;
4052 seed ^= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52;
4053 }
4054 return (seed);
4055 }
4056
4057 void
isp_prt(ispsoftc_t * isp,int level,const char * fmt,...)4058 isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
4059 {
4060 int loc;
4061 char lbuf[200];
4062 va_list ap;
4063
4064 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
4065 return;
4066 }
4067 snprintf(lbuf, sizeof (lbuf), "%s: ", device_get_nameunit(isp->isp_dev));
4068 loc = strlen(lbuf);
4069 va_start(ap, fmt);
4070 vsnprintf(&lbuf[loc], sizeof (lbuf) - loc - 1, fmt, ap);
4071 va_end(ap);
4072 printf("%s\n", lbuf);
4073 }
4074
4075 void
isp_xs_prt(ispsoftc_t * isp,XS_T * xs,int level,const char * fmt,...)4076 isp_xs_prt(ispsoftc_t *isp, XS_T *xs, int level, const char *fmt, ...)
4077 {
4078 va_list ap;
4079 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
4080 return;
4081 }
4082 xpt_print_path(xs->ccb_h.path);
4083 va_start(ap, fmt);
4084 vprintf(fmt, ap);
4085 va_end(ap);
4086 printf("\n");
4087 }
4088
4089 uint64_t
isp_nanotime_sub(struct timespec * b,struct timespec * a)4090 isp_nanotime_sub(struct timespec *b, struct timespec *a)
4091 {
4092 uint64_t elapsed;
4093 struct timespec x;
4094
4095 timespecsub(b, a, &x);
4096 elapsed = GET_NANOSEC(&x);
4097 if (elapsed == 0)
4098 elapsed++;
4099 return (elapsed);
4100 }
4101
4102 int
isp_mbox_acquire(ispsoftc_t * isp)4103 isp_mbox_acquire(ispsoftc_t *isp)
4104 {
4105 if (isp->isp_osinfo.mboxbsy) {
4106 return (1);
4107 } else {
4108 isp->isp_osinfo.mboxcmd_done = 0;
4109 isp->isp_osinfo.mboxbsy = 1;
4110 return (0);
4111 }
4112 }
4113
4114 void
isp_mbox_wait_complete(ispsoftc_t * isp,mbreg_t * mbp)4115 isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
4116 {
4117 u_int t, to;
4118
4119 to = (mbp->timeout == 0) ? MBCMD_DEFAULT_TIMEOUT : mbp->timeout;
4120 if (isp->isp_osinfo.mbox_sleep_ok) {
4121 isp->isp_osinfo.mbox_sleep_ok = 0;
4122 isp->isp_osinfo.mbox_sleeping = 1;
4123 msleep_sbt(&isp->isp_osinfo.mboxcmd_done, &isp->isp_lock,
4124 PRIBIO, "ispmbx_sleep", to * SBT_1US, 0, 0);
4125 isp->isp_osinfo.mbox_sleep_ok = 1;
4126 isp->isp_osinfo.mbox_sleeping = 0;
4127 } else {
4128 for (t = 0; t < to; t += 100) {
4129 if (isp->isp_osinfo.mboxcmd_done)
4130 break;
4131 ISP_RUN_ISR(isp);
4132 if (isp->isp_osinfo.mboxcmd_done)
4133 break;
4134 ISP_DELAY(100);
4135 }
4136 }
4137 if (isp->isp_osinfo.mboxcmd_done == 0) {
4138 isp_prt(isp, ISP_LOGWARN, "%s Mailbox Command (0x%x) Timeout (%uus) (%s:%d)",
4139 isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled",
4140 isp->isp_lastmbxcmd, to, mbp->func, mbp->lineno);
4141 mbp->param[0] = MBOX_TIMEOUT;
4142 isp->isp_osinfo.mboxcmd_done = 1;
4143 }
4144 }
4145
4146 void
isp_mbox_notify_done(ispsoftc_t * isp)4147 isp_mbox_notify_done(ispsoftc_t *isp)
4148 {
4149 isp->isp_osinfo.mboxcmd_done = 1;
4150 if (isp->isp_osinfo.mbox_sleeping)
4151 wakeup(&isp->isp_osinfo.mboxcmd_done);
4152 }
4153
4154 void
isp_mbox_release(ispsoftc_t * isp)4155 isp_mbox_release(ispsoftc_t *isp)
4156 {
4157 isp->isp_osinfo.mboxbsy = 0;
4158 }
4159
4160 int
isp_fc_scratch_acquire(ispsoftc_t * isp,int chan)4161 isp_fc_scratch_acquire(ispsoftc_t *isp, int chan)
4162 {
4163 int ret = 0;
4164 if (isp->isp_osinfo.pc.fc[chan].fcbsy) {
4165 ret = -1;
4166 } else {
4167 isp->isp_osinfo.pc.fc[chan].fcbsy = 1;
4168 }
4169 return (ret);
4170 }
4171
4172 void
isp_platform_intr(void * arg)4173 isp_platform_intr(void *arg)
4174 {
4175 ispsoftc_t *isp = arg;
4176
4177 ISP_LOCK(isp);
4178 ISP_RUN_ISR(isp);
4179 ISP_UNLOCK(isp);
4180 }
4181
4182 void
isp_platform_intr_resp(void * arg)4183 isp_platform_intr_resp(void *arg)
4184 {
4185 ispsoftc_t *isp = arg;
4186
4187 ISP_LOCK(isp);
4188 isp_intr_respq(isp);
4189 ISP_UNLOCK(isp);
4190
4191 /* We have handshake enabled, so explicitly complete interrupt */
4192 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
4193 }
4194
4195 void
isp_platform_intr_atio(void * arg)4196 isp_platform_intr_atio(void *arg)
4197 {
4198 ispsoftc_t *isp = arg;
4199
4200 ISP_LOCK(isp);
4201 #ifdef ISP_TARGET_MODE
4202 isp_intr_atioq(isp);
4203 #endif
4204 ISP_UNLOCK(isp);
4205
4206 /* We have handshake enabled, so explicitly complete interrupt */
4207 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
4208 }
4209
4210 void
isp_common_dmateardown(ispsoftc_t * isp,struct ccb_scsiio * csio,uint32_t hdl)4211 isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl)
4212 {
4213 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
4214 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTREAD);
4215 } else {
4216 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTWRITE);
4217 }
4218 bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap);
4219 }
4220
4221 /*
4222 * Reset the command reference number for all LUNs on a specific target
4223 * (needed when a target arrives again) or for all targets on a port
4224 * (needed for events like a LIP).
4225 */
4226 void
isp_fcp_reset_crn(ispsoftc_t * isp,int chan,uint32_t tgt,int tgt_set)4227 isp_fcp_reset_crn(ispsoftc_t *isp, int chan, uint32_t tgt, int tgt_set)
4228 {
4229 struct isp_fc *fc = ISP_FC_PC(isp, chan);
4230 struct isp_nexus *nxp;
4231 int i;
4232
4233 if (tgt_set == 0)
4234 isp_prt(isp, ISP_LOGDEBUG0,
4235 "Chan %d resetting CRN on all targets", chan);
4236 else
4237 isp_prt(isp, ISP_LOGDEBUG0,
4238 "Chan %d resetting CRN on target %u", chan, tgt);
4239
4240 for (i = 0; i < NEXUS_HASH_WIDTH; i++) {
4241 for (nxp = fc->nexus_hash[i]; nxp != NULL; nxp = nxp->next) {
4242 if (tgt_set == 0 || tgt == nxp->tgt)
4243 nxp->crnseed = 0;
4244 }
4245 }
4246 }
4247
4248 int
isp_fcp_next_crn(ispsoftc_t * isp,uint8_t * crnp,XS_T * cmd)4249 isp_fcp_next_crn(ispsoftc_t *isp, uint8_t *crnp, XS_T *cmd)
4250 {
4251 lun_id_t lun;
4252 uint32_t chan, tgt;
4253 struct isp_fc *fc;
4254 struct isp_nexus *nxp;
4255 int idx;
4256
4257 if (IS_2100(isp))
4258 return (0);
4259
4260 chan = XS_CHANNEL(cmd);
4261 tgt = XS_TGT(cmd);
4262 lun = XS_LUN(cmd);
4263 fc = &isp->isp_osinfo.pc.fc[chan];
4264 idx = NEXUS_HASH(tgt, lun);
4265 nxp = fc->nexus_hash[idx];
4266
4267 while (nxp) {
4268 if (nxp->tgt == tgt && nxp->lun == lun)
4269 break;
4270 nxp = nxp->next;
4271 }
4272 if (nxp == NULL) {
4273 nxp = fc->nexus_free_list;
4274 if (nxp == NULL) {
4275 nxp = malloc(sizeof (struct isp_nexus), M_DEVBUF, M_ZERO|M_NOWAIT);
4276 if (nxp == NULL) {
4277 return (-1);
4278 }
4279 } else {
4280 fc->nexus_free_list = nxp->next;
4281 }
4282 nxp->tgt = tgt;
4283 nxp->lun = lun;
4284 nxp->next = fc->nexus_hash[idx];
4285 fc->nexus_hash[idx] = nxp;
4286 }
4287 if (nxp->crnseed == 0)
4288 nxp->crnseed = 1;
4289 *crnp = nxp->crnseed++;
4290 return (0);
4291 }
4292
4293 /*
4294 * We enter with the lock held
4295 */
4296 void
isp_timer(void * arg)4297 isp_timer(void *arg)
4298 {
4299 ispsoftc_t *isp = arg;
4300 #ifdef ISP_TARGET_MODE
4301 isp_tmcmd_restart(isp);
4302 #endif
4303 callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp);
4304 }
4305
4306 isp_ecmd_t *
isp_get_ecmd(ispsoftc_t * isp)4307 isp_get_ecmd(ispsoftc_t *isp)
4308 {
4309 isp_ecmd_t *ecmd = isp->isp_osinfo.ecmd_free;
4310 if (ecmd) {
4311 isp->isp_osinfo.ecmd_free = ecmd->next;
4312 }
4313 return (ecmd);
4314 }
4315
4316 void
isp_put_ecmd(ispsoftc_t * isp,isp_ecmd_t * ecmd)4317 isp_put_ecmd(ispsoftc_t *isp, isp_ecmd_t *ecmd)
4318 {
4319 ecmd->next = isp->isp_osinfo.ecmd_free;
4320 isp->isp_osinfo.ecmd_free = ecmd;
4321 }
4322