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