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