]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/isp/isp_freebsd.c
Fix Fibre Channel Command Reference Number handling in the isp(4) driver.
[FreeBSD/FreeBSD.git] / sys / dev / isp / isp_freebsd.c
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$");
32 #include <dev/isp/isp_freebsd.h>
33 #include <sys/unistd.h>
34 #include <sys/kthread.h>
35 #include <sys/conf.h>
36 #include <sys/module.h>
37 #include <sys/ioccom.h>
38 #include <dev/isp/isp_ioctl.h>
39 #include <sys/devicestat.h>
40 #include <cam/cam_periph.h>
41 #include <cam/cam_xpt_periph.h>
42
43 #if     __FreeBSD_version < 800002 
44 #define THREAD_CREATE   kthread_create
45 #else
46 #define THREAD_CREATE   kproc_create
47 #endif
48
49 MODULE_VERSION(isp, 1);
50 MODULE_DEPEND(isp, cam, 1, 1, 1);
51 int isp_announced = 0;
52 int isp_fabric_hysteresis = 5;
53 int isp_loop_down_limit = 60;   /* default loop down limit */
54 int isp_change_is_bad = 0;      /* "changed" devices are bad */
55 int isp_quickboot_time = 7;     /* don't wait more than N secs for loop up */
56 int isp_gone_device_time = 30;  /* grace time before reporting device lost */
57 int isp_autoconfig = 1;         /* automatically attach/detach devices */
58 static const char prom3[] = "Chan %d PortID 0x%06x Departed from Target %u because of %s";
59
60 static void isp_freeze_loopdown(ispsoftc_t *, int, char *);
61 static d_ioctl_t ispioctl;
62 static void isp_intr_enable(void *);
63 static void isp_cam_async(void *, uint32_t, struct cam_path *, void *);
64 static void isp_poll(struct cam_sim *);
65 static timeout_t isp_watchdog;
66 static timeout_t isp_gdt;
67 static task_fn_t isp_gdt_task;
68 static timeout_t isp_ldt;
69 static task_fn_t isp_ldt_task;
70 static void isp_kthread(void *);
71 static void isp_action(struct cam_sim *, union ccb *);
72 #ifdef  ISP_INTERNAL_TARGET
73 static void isp_target_thread_pi(void *);
74 static void isp_target_thread_fc(void *);
75 #endif
76 static int isp_timer_count;
77 static void isp_timer(void *);
78
79 static struct cdevsw isp_cdevsw = {
80         .d_version =    D_VERSION,
81         .d_ioctl =      ispioctl,
82         .d_name =       "isp",
83 };
84
85 static int
86 isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
87 {
88         struct ccb_setasync csa;
89         struct cam_sim *sim;
90         struct cam_path *path;
91
92         /*
93          * Construct our SIM entry.
94          */
95         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);
96
97         if (sim == NULL) {
98                 return (ENOMEM);
99         }
100
101         ISP_LOCK(isp);
102         if (xpt_bus_register(sim, isp->isp_dev, chan) != CAM_SUCCESS) {
103                 ISP_UNLOCK(isp);
104                 cam_sim_free(sim, FALSE);
105                 return (EIO);
106         }
107         ISP_UNLOCK(isp);
108         if (xpt_create_path(&path, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
109                 ISP_LOCK(isp);
110                 xpt_bus_deregister(cam_sim_path(sim));
111                 ISP_UNLOCK(isp);
112                 cam_sim_free(sim, FALSE);
113                 return (ENXIO);
114         }
115         xpt_setup_ccb(&csa.ccb_h, path, 5);
116         csa.ccb_h.func_code = XPT_SASYNC_CB;
117         csa.event_enable = AC_LOST_DEVICE;
118         csa.callback = isp_cam_async;
119         csa.callback_arg = sim;
120
121         ISP_LOCK(isp);
122         xpt_action((union ccb *)&csa);
123         ISP_UNLOCK(isp);
124
125         if (IS_SCSI(isp)) {
126                 struct isp_spi *spi = ISP_SPI_PC(isp, chan);
127                 spi->sim = sim;
128                 spi->path = path;
129 #ifdef  ISP_INTERNAL_TARGET
130                 ISP_SET_PC(isp, chan, proc_active, 1);
131                 if (THREAD_CREATE(isp_target_thread_pi, spi, &spi->target_proc, 0, 0, "%s: isp_test_tgt%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
132                         ISP_SET_PC(isp, chan, proc_active, 0);
133                         isp_prt(isp, ISP_LOGERR, "cannot create test target thread");
134                 }
135                 ISP_SPI_PC(isp, chan)->num_threads += 1;
136 #endif
137         } else {
138                 fcparam *fcp = FCPARAM(isp, chan);
139                 struct isp_fc *fc = ISP_FC_PC(isp, chan);
140
141                 ISP_LOCK(isp);
142                 fc->sim = sim;
143                 fc->path = path;
144                 fc->isp = isp;
145                 fc->ready = 1;
146
147                 callout_init_mtx(&fc->ldt, &isp->isp_osinfo.lock, 0);
148                 callout_init_mtx(&fc->gdt, &isp->isp_osinfo.lock, 0);
149                 TASK_INIT(&fc->ltask, 1, isp_ldt_task, fc);
150                 TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc);
151
152                 /*
153                  * We start by being "loop down" if we have an initiator role
154                  */
155                 if (fcp->role & ISP_ROLE_INITIATOR) {
156                         isp_freeze_loopdown(isp, chan, "isp_attach");
157                         callout_reset(&fc->ldt, isp_quickboot_time * hz, isp_ldt, fc);
158                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Initial Loop Down Timer @ %lu", (unsigned long) time_uptime);
159                 }
160                 ISP_UNLOCK(isp);
161                 if (THREAD_CREATE(isp_kthread, fc, &fc->kproc, 0, 0, "%s: fc_thrd%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
162                         xpt_free_path(fc->path);
163                         ISP_LOCK(isp);
164                         if (callout_active(&fc->ldt))
165                                 callout_stop(&fc->ldt);
166                         xpt_bus_deregister(cam_sim_path(fc->sim));
167                         ISP_UNLOCK(isp);
168                         cam_sim_free(fc->sim, FALSE);
169                         return (ENOMEM);
170                 }
171                 ISP_FC_PC(isp, chan)->num_threads += 1;
172 #ifdef  ISP_INTERNAL_TARGET
173                 ISP_SET_PC(isp, chan, proc_active, 1);
174                 if (THREAD_CREATE(isp_target_thread_fc, fc, &fc->target_proc, 0, 0, "%s: isp_test_tgt%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
175                         ISP_SET_PC(isp, chan, proc_active, 0);
176                         isp_prt(isp, ISP_LOGERR, "cannot create test target thread");
177                 }
178                 ISP_FC_PC(isp, chan)->num_threads += 1;
179 #endif
180                 if (chan == 0) {
181                         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(isp->isp_osinfo.dev);
182                         struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev);
183                         SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwnn", CTLFLAG_RD, &FCPARAM(isp, 0)->isp_wwnn, "World Wide Node Name");
184                         SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwpn", CTLFLAG_RD, &FCPARAM(isp, 0)->isp_wwpn, "World Wide Port Name");
185                         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "loop_down_limit", CTLFLAG_RW, &ISP_FC_PC(isp, 0)->loop_down_limit, 0, "Loop Down Limit");
186                         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "gone_device_time", CTLFLAG_RW, &ISP_FC_PC(isp, 0)->gone_device_time, 0, "Gone Device Time");
187 #if defined(ISP_TARGET_MODE) && defined(DEBUG)
188                         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "inject_lost_data_frame", CTLFLAG_RW, &ISP_FC_PC(isp, 0)->inject_lost_data_frame, 0, "Cause a Lost Frame on a Read");
189 #endif
190                 }
191         }
192         return (0);
193 }
194
195 static void
196 isp_detach_internal_target(ispsoftc_t *isp, int chan)
197 {
198 #ifdef ISP_INTERNAL_TARGET
199         void *wchan;
200
201         ISP_GET_PC(isp, chan, target_proc, wchan);
202         ISP_SET_PC(isp, chan, proc_active, 0);
203         wakeup(wchan);
204 #endif
205 }
206
207 static void
208 isp_detach_chan(ispsoftc_t *isp, int chan)
209 {
210         struct cam_sim *sim;
211         struct cam_path *path;
212         struct ccb_setasync csa;
213         int *num_threads;
214
215         ISP_GET_PC(isp, chan, sim, sim);
216         ISP_GET_PC(isp, chan, path, path);
217         ISP_GET_PC_ADDR(isp, chan, num_threads, num_threads);
218
219         xpt_setup_ccb(&csa.ccb_h, path, 5);
220         csa.ccb_h.func_code = XPT_SASYNC_CB;
221         csa.event_enable = 0;
222         csa.callback = isp_cam_async;
223         csa.callback_arg = sim;
224         xpt_action((union ccb *)&csa);
225         xpt_free_path(path);
226         xpt_bus_deregister(cam_sim_path(sim));
227         cam_sim_free(sim, FALSE);
228
229         /* Wait for the channel's spawned threads to exit. */
230         wakeup(isp->isp_osinfo.pc.ptr);
231         isp_detach_internal_target(isp, chan);
232         while (*num_threads != 0)
233                 mtx_sleep(isp, &isp->isp_osinfo.lock, PRIBIO, "isp_reap", 100);
234 }
235
236 int
237 isp_attach(ispsoftc_t *isp)
238 {
239         const char *nu = device_get_nameunit(isp->isp_osinfo.dev);
240         int du = device_get_unit(isp->isp_dev);
241         int chan;
242
243         isp->isp_osinfo.ehook.ich_func = isp_intr_enable;
244         isp->isp_osinfo.ehook.ich_arg = isp;
245         /*
246          * Haha. Set this first, because if we're loaded as a module isp_intr_enable
247          * will be called right awawy, which will clear isp_osinfo.ehook_active,
248          * which would be unwise to then set again later.
249          */
250         isp->isp_osinfo.ehook_active = 1;
251         if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) {
252                 isp_prt(isp, ISP_LOGERR, "could not establish interrupt enable hook");
253                 return (-EIO);
254         }
255
256         /*
257          * Create the device queue for our SIM(s).
258          */
259         isp->isp_osinfo.devq = cam_simq_alloc(isp->isp_maxcmds);
260         if (isp->isp_osinfo.devq == NULL) {
261                 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
262                 return (EIO);
263         }
264
265         for (chan = 0; chan < isp->isp_nchan; chan++) {
266                 if (isp_attach_chan(isp, isp->isp_osinfo.devq, chan)) {
267                         goto unwind;
268                 }
269         }
270
271         callout_init_mtx(&isp->isp_osinfo.tmo, &isp->isp_osinfo.lock, 0);
272         isp_timer_count = hz >> 2;
273         callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp);
274         isp->isp_osinfo.timer_active = 1;
275
276         isp->isp_osinfo.cdev = make_dev(&isp_cdevsw, du, UID_ROOT, GID_OPERATOR, 0600, "%s", nu);
277         if (isp->isp_osinfo.cdev) {
278                 isp->isp_osinfo.cdev->si_drv1 = isp;
279         }
280         return (0);
281
282 unwind:
283         while (--chan >= 0) {
284                 struct cam_sim *sim;
285                 struct cam_path *path;
286
287                 ISP_GET_PC(isp, chan, sim, sim);
288                 ISP_GET_PC(isp, chan, path, path);
289                 xpt_free_path(path);
290                 ISP_LOCK(isp);
291                 xpt_bus_deregister(cam_sim_path(sim));
292                 ISP_UNLOCK(isp);
293                 cam_sim_free(sim, FALSE);
294         }
295         if (isp->isp_osinfo.ehook_active) {
296                 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
297                 isp->isp_osinfo.ehook_active = 0;
298         }
299         if (isp->isp_osinfo.cdev) {
300                 destroy_dev(isp->isp_osinfo.cdev);
301                 isp->isp_osinfo.cdev = NULL;
302         }
303         cam_simq_free(isp->isp_osinfo.devq);
304         isp->isp_osinfo.devq = NULL;
305         return (-1);
306 }
307
308 int
309 isp_detach(ispsoftc_t *isp)
310 {
311         struct cam_sim *sim;
312         int chan;
313
314         ISP_LOCK(isp);
315         for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1) {
316                 ISP_GET_PC(isp, chan, sim, sim);
317                 if (sim->refcount > 2) {
318                         ISP_UNLOCK(isp);
319                         return (EBUSY);
320                 }
321         }
322         /* Tell spawned threads that we're exiting. */
323         isp->isp_osinfo.is_exiting = 1;
324         if (isp->isp_osinfo.timer_active) {
325                 callout_stop(&isp->isp_osinfo.tmo);
326                 isp->isp_osinfo.timer_active = 0;
327         }
328         for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1)
329                 isp_detach_chan(isp, chan);
330         ISP_UNLOCK(isp);
331
332         if (isp->isp_osinfo.cdev) {
333                 destroy_dev(isp->isp_osinfo.cdev);
334                 isp->isp_osinfo.cdev = NULL;
335         }
336         if (isp->isp_osinfo.ehook_active) {
337                 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
338                 isp->isp_osinfo.ehook_active = 0;
339         }
340         if (isp->isp_osinfo.devq != NULL) {
341                 cam_simq_free(isp->isp_osinfo.devq);
342                 isp->isp_osinfo.devq = NULL;
343         }
344         return (0);
345 }
346
347 static void
348 isp_freeze_loopdown(ispsoftc_t *isp, int chan, char *msg)
349 {
350         if (IS_FC(isp)) {
351                 struct isp_fc *fc = ISP_FC_PC(isp, chan);
352                 if (fc->simqfrozen == 0) {
353                         isp_prt(isp, ISP_LOGDEBUG0, "%s: freeze simq (loopdown) chan %d", msg, chan);
354                         fc->simqfrozen = SIMQFRZ_LOOPDOWN;
355                         xpt_freeze_simq(fc->sim, 1);
356                 } else {
357                         isp_prt(isp, ISP_LOGDEBUG0, "%s: mark frozen (loopdown) chan %d", msg, chan);
358                         fc->simqfrozen |= SIMQFRZ_LOOPDOWN;
359                 }
360         }
361 }
362
363 static void
364 isp_unfreeze_loopdown(ispsoftc_t *isp, int chan)
365 {
366         if (IS_FC(isp)) {
367                 struct isp_fc *fc = ISP_FC_PC(isp, chan);
368                 int wasfrozen = fc->simqfrozen & SIMQFRZ_LOOPDOWN;
369                 fc->simqfrozen &= ~SIMQFRZ_LOOPDOWN;
370                 if (wasfrozen && fc->simqfrozen == 0) {
371                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d releasing simq", __func__, chan);
372                         xpt_release_simq(fc->sim, 1);
373                 }
374         }
375 }
376
377
378 static int
379 ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
380 {
381         ispsoftc_t *isp;
382         int nr, chan, retval = ENOTTY;
383
384         isp = dev->si_drv1;
385
386         switch (c) {
387         case ISP_SDBLEV:
388         {
389                 int olddblev = isp->isp_dblev;
390                 isp->isp_dblev = *(int *)addr;
391                 *(int *)addr = olddblev;
392                 retval = 0;
393                 break;
394         }
395         case ISP_GETROLE:
396                 chan = *(int *)addr;
397                 if (chan < 0 || chan >= isp->isp_nchan) {
398                         retval = -ENXIO;
399                         break;
400                 }
401                 if (IS_FC(isp)) {
402                         *(int *)addr = FCPARAM(isp, chan)->role;
403                 } else {
404                         *(int *)addr = SDPARAM(isp, chan)->role;
405                 }
406                 retval = 0;
407                 break;
408         case ISP_SETROLE:
409                 nr = *(int *)addr;
410                 chan = nr >> 8;
411                 if (chan < 0 || chan >= isp->isp_nchan) {
412                         retval = -ENXIO;
413                         break;
414                 }
415                 nr &= 0xff;
416                 if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
417                         retval = EINVAL;
418                         break;
419                 }
420                 if (IS_FC(isp)) {
421                         /*
422                          * We don't really support dual role at present on FC cards.
423                          *
424                          * We should, but a bunch of things are currently broken,
425                          * so don't allow it.
426                          */
427                         if (nr == ISP_ROLE_BOTH) {
428                                 isp_prt(isp, ISP_LOGERR, "cannot support dual role at present");
429                                 retval = EINVAL;
430                                 break;
431                         }
432                         *(int *)addr = FCPARAM(isp, chan)->role;
433 #ifdef  ISP_INTERNAL_TARGET
434                         ISP_LOCK(isp);
435                         retval = isp_fc_change_role(isp, chan, nr);
436                         ISP_UNLOCK(isp);
437 #else
438                         FCPARAM(isp, chan)->role = nr;
439 #endif
440                 } else {
441                         *(int *)addr = SDPARAM(isp, chan)->role;
442                         SDPARAM(isp, chan)->role = nr;
443                 }
444                 retval = 0;
445                 break;
446
447         case ISP_RESETHBA:
448                 ISP_LOCK(isp);
449 #ifdef  ISP_TARGET_MODE
450                 isp_del_all_wwn_entries(isp, ISP_NOCHAN);
451 #endif
452                 isp_reinit(isp, 0);
453                 ISP_UNLOCK(isp);
454                 retval = 0;
455                 break;
456
457         case ISP_RESCAN:
458                 if (IS_FC(isp)) {
459                         chan = *(int *)addr;
460                         if (chan < 0 || chan >= isp->isp_nchan) {
461                                 retval = -ENXIO;
462                                 break;
463                         }
464                         ISP_LOCK(isp);
465                         if (isp_fc_runstate(isp, chan, 5 * 1000000)) {
466                                 retval = EIO;
467                         } else {
468                                 retval = 0;
469                         }
470                         ISP_UNLOCK(isp);
471                 }
472                 break;
473
474         case ISP_FC_LIP:
475                 if (IS_FC(isp)) {
476                         chan = *(int *)addr;
477                         if (chan < 0 || chan >= isp->isp_nchan) {
478                                 retval = -ENXIO;
479                                 break;
480                         }
481                         ISP_LOCK(isp);
482                         if (isp_control(isp, ISPCTL_SEND_LIP, chan)) {
483                                 retval = EIO;
484                         } else {
485                                 retval = 0;
486                         }
487                         ISP_UNLOCK(isp);
488                 }
489                 break;
490         case ISP_FC_GETDINFO:
491         {
492                 struct isp_fc_device *ifc = (struct isp_fc_device *) addr;
493                 fcportdb_t *lp;
494
495                 if (IS_SCSI(isp)) {
496                         break;
497                 }
498                 if (ifc->loopid >= MAX_FC_TARG) {
499                         retval = EINVAL;
500                         break;
501                 }
502                 lp = &FCPARAM(isp, ifc->chan)->portdb[ifc->loopid];
503                 if (lp->state == FC_PORTDB_STATE_VALID || lp->target_mode) {
504                         ifc->role = (lp->prli_word3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
505                         ifc->loopid = lp->handle;
506                         ifc->portid = lp->portid;
507                         ifc->node_wwn = lp->node_wwn;
508                         ifc->port_wwn = lp->port_wwn;
509                         retval = 0;
510                 } else {
511                         retval = ENODEV;
512                 }
513                 break;
514         }
515         case ISP_GET_STATS:
516         {
517                 isp_stats_t *sp = (isp_stats_t *) addr;
518
519                 ISP_MEMZERO(sp, sizeof (*sp));
520                 sp->isp_stat_version = ISP_STATS_VERSION;
521                 sp->isp_type = isp->isp_type;
522                 sp->isp_revision = isp->isp_revision;
523                 ISP_LOCK(isp);
524                 sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt;
525                 sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
526                 sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
527                 sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;
528                 sp->isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt;
529                 sp->isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt;
530                 sp->isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater;
531                 sp->isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater;
532                 ISP_UNLOCK(isp);
533                 retval = 0;
534                 break;
535         }
536         case ISP_CLR_STATS:
537                 ISP_LOCK(isp);
538                 isp->isp_intcnt = 0;
539                 isp->isp_intbogus = 0;
540                 isp->isp_intmboxc = 0;
541                 isp->isp_intoasync = 0;
542                 isp->isp_rsltccmplt = 0;
543                 isp->isp_fphccmplt = 0;
544                 isp->isp_rscchiwater = 0;
545                 isp->isp_fpcchiwater = 0;
546                 ISP_UNLOCK(isp);
547                 retval = 0;
548                 break;
549         case ISP_FC_GETHINFO:
550         {
551                 struct isp_hba_device *hba = (struct isp_hba_device *) addr;
552                 int chan = hba->fc_channel;
553
554                 if (chan < 0 || chan >= isp->isp_nchan) {
555                         retval = ENXIO;
556                         break;
557                 }
558                 hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev);
559                 hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev);
560                 hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev);
561                 hba->fc_nchannels = isp->isp_nchan;
562                 if (IS_FC(isp)) {
563                         hba->fc_nports = MAX_FC_TARG;
564                         hba->fc_speed = FCPARAM(isp, hba->fc_channel)->isp_gbspeed;
565                         hba->fc_topology = FCPARAM(isp, chan)->isp_topo + 1;
566                         hba->fc_loopid = FCPARAM(isp, chan)->isp_loopid;
567                         hba->nvram_node_wwn = FCPARAM(isp, chan)->isp_wwnn_nvram;
568                         hba->nvram_port_wwn = FCPARAM(isp, chan)->isp_wwpn_nvram;
569                         hba->active_node_wwn = FCPARAM(isp, chan)->isp_wwnn;
570                         hba->active_port_wwn = FCPARAM(isp, chan)->isp_wwpn;
571                 } else {
572                         hba->fc_nports = MAX_TARGETS;
573                         hba->fc_speed = 0;
574                         hba->fc_topology = 0;
575                         hba->nvram_node_wwn = 0ull;
576                         hba->nvram_port_wwn = 0ull;
577                         hba->active_node_wwn = 0ull;
578                         hba->active_port_wwn = 0ull;
579                 }
580                 retval = 0;
581                 break;
582         }
583         case ISP_TSK_MGMT:
584         {
585                 int needmarker;
586                 struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
587                 uint16_t loopid;
588                 mbreg_t mbs;
589
590                 if (IS_SCSI(isp)) {
591                         break;
592                 }
593
594                 chan = fct->chan;
595                 if (chan < 0 || chan >= isp->isp_nchan) {
596                         retval = -ENXIO;
597                         break;
598                 }
599
600                 needmarker = retval = 0;
601                 loopid = fct->loopid;
602                 ISP_LOCK(isp);
603                 if (IS_24XX(isp)) {
604                         uint8_t local[QENTRY_LEN];
605                         isp24xx_tmf_t *tmf;
606                         isp24xx_statusreq_t *sp;
607                         fcparam *fcp = FCPARAM(isp, chan);
608                         fcportdb_t *lp;
609                         int i;
610
611                         for (i = 0; i < MAX_FC_TARG; i++) {
612                                 lp = &fcp->portdb[i];
613                                 if (lp->handle == loopid) {
614                                         break;
615                                 }
616                         }
617                         if (i == MAX_FC_TARG) {
618                                 retval = ENXIO;
619                                 ISP_UNLOCK(isp);
620                                 break;
621                         }
622                         /* XXX VALIDATE LP XXX */
623                         tmf = (isp24xx_tmf_t *) local;
624                         ISP_MEMZERO(tmf, QENTRY_LEN);
625                         tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
626                         tmf->tmf_header.rqs_entry_count = 1;
627                         tmf->tmf_nphdl = lp->handle;
628                         tmf->tmf_delay = 2;
629                         tmf->tmf_timeout = 2;
630                         tmf->tmf_tidlo = lp->portid;
631                         tmf->tmf_tidhi = lp->portid >> 16;
632                         tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
633                         tmf->tmf_lun[1] = fct->lun & 0xff;
634                         if (fct->lun >= 256) {
635                                 tmf->tmf_lun[0] = 0x40 | (fct->lun >> 8);
636                         }
637                         switch (fct->action) {
638                         case IPT_CLEAR_ACA:
639                                 tmf->tmf_flags = ISP24XX_TMF_CLEAR_ACA;
640                                 break;
641                         case IPT_TARGET_RESET:
642                                 tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
643                                 needmarker = 1;
644                                 break;
645                         case IPT_LUN_RESET:
646                                 tmf->tmf_flags = ISP24XX_TMF_LUN_RESET;
647                                 needmarker = 1;
648                                 break;
649                         case IPT_CLEAR_TASK_SET:
650                                 tmf->tmf_flags = ISP24XX_TMF_CLEAR_TASK_SET;
651                                 needmarker = 1;
652                                 break;
653                         case IPT_ABORT_TASK_SET:
654                                 tmf->tmf_flags = ISP24XX_TMF_ABORT_TASK_SET;
655                                 needmarker = 1;
656                                 break;
657                         default:
658                                 retval = EINVAL;
659                                 break;
660                         }
661                         if (retval) {
662                                 ISP_UNLOCK(isp);
663                                 break;
664                         }
665                         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
666                         mbs.param[1] = QENTRY_LEN;
667                         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
668                         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
669                         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
670                         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
671
672                         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
673                                 ISP_UNLOCK(isp);
674                                 retval = ENOMEM;
675                                 break;
676                         }
677                         isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
678                         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
679                         sp = (isp24xx_statusreq_t *) local;
680                         sp->req_completion_status = 1;
681                         retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
682                         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
683                         isp_get_24xx_response(isp, &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
684                         FC_SCRATCH_RELEASE(isp, chan);
685                         if (retval || sp->req_completion_status != 0) {
686                                 FC_SCRATCH_RELEASE(isp, chan);
687                                 retval = EIO;
688                         }
689                         if (retval == 0) {
690                                 if (needmarker) {
691                                         fcp->sendmarker = 1;
692                                 }
693                         }
694                 } else {
695                         MBSINIT(&mbs, 0, MBLOGALL, 0);
696                         if (ISP_CAP_2KLOGIN(isp) == 0) {
697                                 loopid <<= 8;
698                         }
699                         switch (fct->action) {
700                         case IPT_CLEAR_ACA:
701                                 mbs.param[0] = MBOX_CLEAR_ACA;
702                                 mbs.param[1] = loopid;
703                                 mbs.param[2] = fct->lun;
704                                 break;
705                         case IPT_TARGET_RESET:
706                                 mbs.param[0] = MBOX_TARGET_RESET;
707                                 mbs.param[1] = loopid;
708                                 needmarker = 1;
709                                 break;
710                         case IPT_LUN_RESET:
711                                 mbs.param[0] = MBOX_LUN_RESET;
712                                 mbs.param[1] = loopid;
713                                 mbs.param[2] = fct->lun;
714                                 needmarker = 1;
715                                 break;
716                         case IPT_CLEAR_TASK_SET:
717                                 mbs.param[0] = MBOX_CLEAR_TASK_SET;
718                                 mbs.param[1] = loopid;
719                                 mbs.param[2] = fct->lun;
720                                 needmarker = 1;
721                                 break;
722                         case IPT_ABORT_TASK_SET:
723                                 mbs.param[0] = MBOX_ABORT_TASK_SET;
724                                 mbs.param[1] = loopid;
725                                 mbs.param[2] = fct->lun;
726                                 needmarker = 1;
727                                 break;
728                         default:
729                                 retval = EINVAL;
730                                 break;
731                         }
732                         if (retval == 0) {
733                                 if (needmarker) {
734                                         FCPARAM(isp, chan)->sendmarker = 1;
735                                 }
736                                 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
737                                 if (retval) {
738                                         retval = EIO;
739                                 }
740                         }
741                 }
742                 ISP_UNLOCK(isp);
743                 break;
744         }
745         default:
746                 break;
747         }
748         return (retval);
749 }
750
751 static void
752 isp_intr_enable(void *arg)
753 {
754         int chan;
755         ispsoftc_t *isp = arg;
756         ISP_LOCK(isp);
757         for (chan = 0; chan < isp->isp_nchan; chan++) {
758                 if (IS_FC(isp)) {
759                         if (FCPARAM(isp, chan)->role != ISP_ROLE_NONE) {
760                                 ISP_ENABLE_INTS(isp);
761                                 break;
762                         }
763                 } else {
764                         if (SDPARAM(isp, chan)->role != ISP_ROLE_NONE) {
765                                 ISP_ENABLE_INTS(isp);
766                                 break;
767                         }
768                 }
769         }
770         isp->isp_osinfo.ehook_active = 0;
771         ISP_UNLOCK(isp);
772         /* Release our hook so that the boot can continue. */
773         config_intrhook_disestablish(&isp->isp_osinfo.ehook);
774 }
775
776 /*
777  * Local Inlines
778  */
779
780 static ISP_INLINE int isp_get_pcmd(ispsoftc_t *, union ccb *);
781 static ISP_INLINE void isp_free_pcmd(ispsoftc_t *, union ccb *);
782
783 static ISP_INLINE int
784 isp_get_pcmd(ispsoftc_t *isp, union ccb *ccb)
785 {
786         ISP_PCMD(ccb) = isp->isp_osinfo.pcmd_free;
787         if (ISP_PCMD(ccb) == NULL) {
788                 return (-1);
789         }
790         isp->isp_osinfo.pcmd_free = ((struct isp_pcmd *)ISP_PCMD(ccb))->next;
791         return (0);
792 }
793
794 static ISP_INLINE void
795 isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb)
796 {
797         if (ISP_PCMD(ccb)) {
798 #ifdef  ISP_TARGET_MODE
799                 PISP_PCMD(ccb)->datalen = 0;
800                 PISP_PCMD(ccb)->totslen = 0;
801                 PISP_PCMD(ccb)->cumslen = 0;
802                 PISP_PCMD(ccb)->crn = 0;
803 #endif
804                 PISP_PCMD(ccb)->next = isp->isp_osinfo.pcmd_free;
805                 isp->isp_osinfo.pcmd_free = ISP_PCMD(ccb);
806                 ISP_PCMD(ccb) = NULL;
807         }
808 }
809
810 /*
811  * Put the target mode functions here, because some are inlines
812  */
813 #ifdef  ISP_TARGET_MODE
814 static ISP_INLINE void isp_tmlock(ispsoftc_t *, const char *);
815 static ISP_INLINE void isp_tmunlk(ispsoftc_t *);
816 static ISP_INLINE int is_any_lun_enabled(ispsoftc_t *, int);
817 static ISP_INLINE int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
818 static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
819 static ISP_INLINE tstate_t *get_lun_statep_from_tag(ispsoftc_t *, int, uint32_t);
820 static ISP_INLINE void rls_lun_statep(ispsoftc_t *, tstate_t *);
821 static ISP_INLINE inot_private_data_t *get_ntp_from_tagdata(ispsoftc_t *, uint32_t, uint32_t, tstate_t **);
822 static ISP_INLINE atio_private_data_t *isp_get_atpd(ispsoftc_t *, tstate_t *, uint32_t);
823 static ISP_INLINE atio_private_data_t *isp_find_atpd(ispsoftc_t *, tstate_t *, uint32_t);
824 static ISP_INLINE void isp_put_atpd(ispsoftc_t *, tstate_t *, atio_private_data_t *);
825 static ISP_INLINE inot_private_data_t *isp_get_ntpd(ispsoftc_t *, tstate_t *);
826 static ISP_INLINE inot_private_data_t *isp_find_ntpd(ispsoftc_t *, tstate_t *, uint32_t, uint32_t);
827 static ISP_INLINE void isp_put_ntpd(ispsoftc_t *, tstate_t *, inot_private_data_t *);
828 static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
829 static void destroy_lun_state(ispsoftc_t *, tstate_t *);
830 static void isp_enable_lun(ispsoftc_t *, union ccb *);
831 static cam_status isp_enable_deferred_luns(ispsoftc_t *, int);
832 static cam_status isp_enable_deferred(ispsoftc_t *, int, lun_id_t);
833 static void isp_disable_lun(ispsoftc_t *, union ccb *);
834 static int isp_enable_target_mode(ispsoftc_t *, int);
835 static int isp_disable_target_mode(ispsoftc_t *, int);
836 static void isp_ledone(ispsoftc_t *, lun_entry_t *);
837 static timeout_t isp_refire_putback_atio;
838 static timeout_t isp_refire_notify_ack;
839 static void isp_complete_ctio(union ccb *);
840 static void isp_target_putback_atio(union ccb *);
841 enum Start_Ctio_How { FROM_CAM, FROM_TIMER, FROM_SRR, FROM_CTIO_DONE };
842 static void isp_target_start_ctio(ispsoftc_t *, union ccb *, enum Start_Ctio_How);
843 static void isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
844 static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
845 static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
846 static void isp_handle_platform_ctio(ispsoftc_t *, void *);
847 static void isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *);
848 static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
849 static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
850 static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *);
851 static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
852 static void isp_target_mark_aborted(ispsoftc_t *, union ccb *);
853 static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t);
854
855 static ISP_INLINE void
856 isp_tmlock(ispsoftc_t *isp, const char *msg)
857 {
858         while (isp->isp_osinfo.tmbusy) {
859                 isp->isp_osinfo.tmwanted = 1;
860                 mtx_sleep(isp, &isp->isp_lock, PRIBIO, msg, 0);
861         }
862         isp->isp_osinfo.tmbusy = 1;
863 }
864
865 static ISP_INLINE void
866 isp_tmunlk(ispsoftc_t *isp)
867 {
868         isp->isp_osinfo.tmbusy = 0;
869         if (isp->isp_osinfo.tmwanted) {
870                 isp->isp_osinfo.tmwanted = 0;
871                 wakeup(isp);
872         }
873 }
874
875 static ISP_INLINE int
876 is_any_lun_enabled(ispsoftc_t *isp, int bus)
877 {
878         struct tslist *lhp;
879         int i;
880
881         for (i = 0; i < LUN_HASH_SIZE; i++) {
882                 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
883                 if (SLIST_FIRST(lhp))
884                         return (1);
885         }
886         return (0);
887 }
888
889 static ISP_INLINE int
890 is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
891 {
892         tstate_t *tptr;
893         struct tslist *lhp;
894
895         ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
896         SLIST_FOREACH(tptr, lhp, next) {
897                 if (tptr->ts_lun == lun) {
898                         return (1);
899                 }
900         }
901         return (0);
902 }
903
904 static void
905 dump_tstates(ispsoftc_t *isp, int bus)
906 {
907         int i, j;
908         struct tslist *lhp;
909         tstate_t *tptr = NULL;
910
911         if (bus >= isp->isp_nchan) {
912                 return;
913         }
914         for (i = 0; i < LUN_HASH_SIZE; i++) {
915                 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
916                 j = 0;
917                 SLIST_FOREACH(tptr, lhp, next) {
918                         xpt_print(tptr->owner, "[%d, %d] atio_cnt=%d inot_cnt=%d\n", i, j, tptr->atio_count, tptr->inot_count);
919                         j++;
920                 }
921         }
922 }
923
924 static ISP_INLINE tstate_t *
925 get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
926 {
927         tstate_t *tptr = NULL;
928         struct tslist *lhp;
929
930         if (bus < isp->isp_nchan) {
931                 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
932                 SLIST_FOREACH(tptr, lhp, next) {
933                         if (tptr->ts_lun == lun) {
934                                 tptr->hold++;
935                                 return (tptr);
936                         }
937                 }
938         }
939         return (NULL);
940 }
941
942 static ISP_INLINE tstate_t *
943 get_lun_statep_from_tag(ispsoftc_t *isp, int bus, uint32_t tagval)
944 {
945         tstate_t *tptr = NULL;
946         atio_private_data_t *atp;
947         struct tslist *lhp;
948         int i;
949
950         if (bus < isp->isp_nchan && tagval != 0) {
951                 for (i = 0; i < LUN_HASH_SIZE; i++) {
952                         ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
953                         SLIST_FOREACH(tptr, lhp, next) {
954                                 atp = isp_find_atpd(isp, tptr, tagval);
955                                 if (atp) {
956                                         tptr->hold++;
957                                         return (tptr);
958                                 }
959                         }
960                 }
961         }
962         return (NULL);
963 }
964
965 static ISP_INLINE inot_private_data_t *
966 get_ntp_from_tagdata(ispsoftc_t *isp, uint32_t tag_id, uint32_t seq_id, tstate_t **rslt)
967 {
968         inot_private_data_t *ntp;
969         tstate_t *tptr;
970         struct tslist *lhp;
971         int bus, i;
972
973         for (bus = 0; bus < isp->isp_nchan; bus++) {
974                 for (i = 0; i < LUN_HASH_SIZE; i++) {
975                         ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
976                         SLIST_FOREACH(tptr, lhp, next) {
977                                 ntp = isp_find_ntpd(isp, tptr, tag_id, seq_id);
978                                 if (ntp) {
979                                         *rslt = tptr;
980                                         tptr->hold++;
981                                         return (ntp);
982                                 }
983                         }
984                 }
985         }
986         return (NULL);
987 }
988
989 static ISP_INLINE void
990 rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
991 {
992         KASSERT((tptr->hold), ("tptr not held"));
993         tptr->hold--;
994 }
995
996 static void
997 isp_tmcmd_restart(ispsoftc_t *isp)
998 {
999         inot_private_data_t *ntp;
1000         inot_private_data_t *restart_queue;
1001         tstate_t *tptr;
1002         union ccb *ccb;
1003         struct tslist *lhp;
1004         int bus, i;
1005
1006         for (bus = 0; bus < isp->isp_nchan; bus++) {
1007                 for (i = 0; i < LUN_HASH_SIZE; i++) {
1008                         ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
1009                         SLIST_FOREACH(tptr, lhp, next) {
1010                                 if ((restart_queue = tptr->restart_queue) != NULL)
1011                                         tptr->restart_queue = NULL;
1012                                 while (restart_queue) {
1013                                         ntp = restart_queue;
1014                                         restart_queue = ntp->rd.nt.nt_hba;
1015                                         if (IS_24XX(isp)) {
1016                                                 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid);
1017                                                 isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data);
1018                                         } else {
1019                                                 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid);
1020                                                 isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data);
1021                                         }
1022                                         isp_put_ntpd(isp, tptr, ntp);
1023                                         if (tptr->restart_queue && restart_queue != NULL) {
1024                                                 ntp = tptr->restart_queue;
1025                                                 tptr->restart_queue = restart_queue;
1026                                                 while (restart_queue->rd.nt.nt_hba) {
1027                                                         restart_queue = restart_queue->rd.nt.nt_hba;
1028                                                 }
1029                                                 restart_queue->rd.nt.nt_hba = ntp;
1030                                                 break;
1031                                         }
1032                                 }
1033                                 /*
1034                                  * We only need to do this once per tptr
1035                                  */
1036                                 if (!TAILQ_EMPTY(&tptr->waitq)) {
1037                                         ccb = (union ccb *)TAILQ_LAST(&tptr->waitq, isp_ccbq);
1038                                         TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
1039                                         isp_target_start_ctio(isp, ccb, FROM_TIMER);
1040                                 }
1041                         }
1042                 }
1043         }
1044 }
1045
1046 static ISP_INLINE atio_private_data_t *
1047 isp_get_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag)
1048 {
1049         atio_private_data_t *atp;
1050
1051         atp = LIST_FIRST(&tptr->atfree);
1052         if (atp) {
1053                 LIST_REMOVE(atp, next);
1054                 atp->tag = tag;
1055                 LIST_INSERT_HEAD(&tptr->atused[ATPDPHASH(tag)], atp, next);
1056         }
1057         return (atp);
1058 }
1059
1060 static ISP_INLINE atio_private_data_t *
1061 isp_find_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag)
1062 {
1063         atio_private_data_t *atp;
1064
1065         LIST_FOREACH(atp, &tptr->atused[ATPDPHASH(tag)], next) {
1066                 if (atp->tag == tag)
1067                         return (atp);
1068         }
1069         return (NULL);
1070 }
1071
1072 static ISP_INLINE void
1073 isp_put_atpd(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp)
1074 {
1075         if (atp->ests) {
1076                 isp_put_ecmd(isp, atp->ests);
1077         }
1078         LIST_REMOVE(atp, next);
1079         memset(atp, 0, sizeof (*atp));
1080         LIST_INSERT_HEAD(&tptr->atfree, atp, next);
1081 }
1082
1083 static void
1084 isp_dump_atpd(ispsoftc_t *isp, tstate_t *tptr)
1085 {
1086         atio_private_data_t *atp;
1087         const char *states[8] = { "Free", "ATIO", "CAM", "CTIO", "LAST_CTIO", "PDON", "?6", "7" };
1088
1089         for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
1090                 xpt_print(tptr->owner, "ATP: [0x%x] origdlen %u bytes_xfrd %u lun %u nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s\n",
1091                     atp->tag, atp->orig_datalen, atp->bytes_xfered, atp->lun, atp->nphdl, atp->sid, atp->portid, atp->oxid, states[atp->state & 0x7]);
1092         }
1093 }
1094
1095
1096 static ISP_INLINE inot_private_data_t *
1097 isp_get_ntpd(ispsoftc_t *isp, tstate_t *tptr)
1098 {
1099         inot_private_data_t *ntp;
1100         ntp = tptr->ntfree;
1101         if (ntp) {
1102                 tptr->ntfree = ntp->next;
1103         }
1104         return (ntp);
1105 }
1106
1107 static ISP_INLINE inot_private_data_t *
1108 isp_find_ntpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id, uint32_t seq_id)
1109 {
1110         inot_private_data_t *ntp;
1111         for (ntp = tptr->ntpool; ntp < &tptr->ntpool[ATPDPSIZE]; ntp++) {
1112                 if (ntp->rd.tag_id == tag_id && ntp->rd.seq_id == seq_id) {
1113                         return (ntp);
1114                 }
1115         }
1116         return (NULL);
1117 }
1118
1119 static ISP_INLINE void
1120 isp_put_ntpd(ispsoftc_t *isp, tstate_t *tptr, inot_private_data_t *ntp)
1121 {
1122         ntp->rd.tag_id = ntp->rd.seq_id = 0;
1123         ntp->next = tptr->ntfree;
1124         tptr->ntfree = ntp;
1125 }
1126
1127 static cam_status
1128 create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rslt)
1129 {
1130         cam_status status;
1131         lun_id_t lun;
1132         struct tslist *lhp;
1133         tstate_t *tptr;
1134         int i;
1135
1136         lun = xpt_path_lun_id(path);
1137         if (lun != CAM_LUN_WILDCARD) {
1138                 if (lun >= ISP_MAX_LUNS(isp)) {
1139                         return (CAM_LUN_INVALID);
1140                 }
1141         }
1142         if (is_lun_enabled(isp, bus, lun)) {
1143                 return (CAM_LUN_ALRDY_ENA);
1144         }
1145         tptr = malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
1146         if (tptr == NULL) {
1147                 return (CAM_RESRC_UNAVAIL);
1148         }
1149         tptr->ts_lun = lun;
1150         status = xpt_create_path(&tptr->owner, NULL, xpt_path_path_id(path), xpt_path_target_id(path), lun);
1151         if (status != CAM_REQ_CMP) {
1152                 free(tptr, M_DEVBUF);
1153                 return (status);
1154         }
1155         SLIST_INIT(&tptr->atios);
1156         SLIST_INIT(&tptr->inots);
1157         TAILQ_INIT(&tptr->waitq);
1158         LIST_INIT(&tptr->atfree);
1159         for (i = ATPDPSIZE-1; i >= 0; i--)
1160                 LIST_INSERT_HEAD(&tptr->atfree, &tptr->atpool[i], next);
1161         for (i = 0; i < ATPDPHASHSIZE; i++)
1162                 LIST_INIT(&tptr->atused[i]);
1163         for (i = 0; i < ATPDPSIZE-1; i++)
1164                 tptr->ntpool[i].next = &tptr->ntpool[i+1];
1165         tptr->ntfree = tptr->ntpool;
1166         tptr->hold = 1;
1167         ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
1168         SLIST_INSERT_HEAD(lhp, tptr, next);
1169         *rslt = tptr;
1170         ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, path, "created tstate\n");
1171         return (CAM_REQ_CMP);
1172 }
1173
1174 static ISP_INLINE void
1175 destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
1176 {
1177         union ccb *ccb;
1178         struct tslist *lhp;
1179
1180         KASSERT((tptr->hold != 0), ("tptr is not held"));
1181         KASSERT((tptr->hold == 1), ("tptr still held (%d)", tptr->hold));
1182         do {
1183                 ccb = (union ccb *)SLIST_FIRST(&tptr->atios);
1184                 if (ccb) {
1185                         SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1186                         ccb->ccb_h.status = CAM_REQ_ABORTED;
1187                         xpt_done(ccb);
1188                 }
1189         } while (ccb);
1190         do {
1191                 ccb = (union ccb *)SLIST_FIRST(&tptr->inots);
1192                 if (ccb) {
1193                         SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
1194                         ccb->ccb_h.status = CAM_REQ_ABORTED;
1195                         xpt_done(ccb);
1196                 }
1197         } while (ccb);
1198         ISP_GET_PC_ADDR(isp, cam_sim_bus(xpt_path_sim(tptr->owner)), lun_hash[LUN_HASH_FUNC(tptr->ts_lun)], lhp);
1199         SLIST_REMOVE(lhp, tptr, tstate, next);
1200         ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "destroyed tstate\n");
1201         xpt_free_path(tptr->owner);
1202         free(tptr, M_DEVBUF);
1203 }
1204
1205 /*
1206  * Enable a lun.
1207  */
1208 static void
1209 isp_enable_lun(ispsoftc_t *isp, union ccb *ccb)
1210 {
1211         tstate_t *tptr = NULL;
1212         int bus, tm_enabled, target_role;
1213         target_id_t target;
1214         lun_id_t lun;
1215
1216
1217         /*
1218          * We only support either a wildcard target/lun or a target ID of zero and a non-wildcard lun
1219          */
1220         bus = XS_CHANNEL(ccb);
1221         target = ccb->ccb_h.target_id;
1222         lun = ccb->ccb_h.target_lun;
1223         ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "enabling lun %u\n", lun);
1224         if (target != CAM_TARGET_WILDCARD && target != 0) {
1225                 ccb->ccb_h.status = CAM_TID_INVALID;
1226                 xpt_done(ccb);
1227                 return;
1228         }
1229         if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
1230                 ccb->ccb_h.status = CAM_LUN_INVALID;
1231                 xpt_done(ccb);
1232                 return;
1233         }
1234
1235         if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
1236                 ccb->ccb_h.status = CAM_LUN_INVALID;
1237                 xpt_done(ccb);
1238                 return;
1239         }
1240         if (isp->isp_dblev & ISP_LOGTDEBUG0) {
1241                 xpt_print(ccb->ccb_h.path, "enabling lun 0x%x on channel %d\n", lun, bus);
1242         }
1243
1244         /*
1245          * Wait until we're not busy with the lun enables subsystem
1246          */
1247         isp_tmlock(isp, "isp_enable_lun");
1248
1249         /*
1250          * This is as a good a place as any to check f/w capabilities.
1251          */
1252
1253         if (IS_FC(isp)) {
1254                 if (ISP_CAP_TMODE(isp) == 0) {
1255                         xpt_print(ccb->ccb_h.path, "firmware does not support target mode\n");
1256                         ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1257                         goto done;
1258                 }
1259                 /*
1260                  * We *could* handle non-SCCLUN f/w, but we'd have to
1261                  * dork with our already fragile enable/disable code.
1262                  */
1263                 if (ISP_CAP_SCCFW(isp) == 0) {
1264                         xpt_print(ccb->ccb_h.path, "firmware not SCCLUN capable\n");
1265                         ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1266                         goto done;
1267                 }
1268
1269                 target_role = (FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) != 0;
1270
1271         } else {
1272                 target_role = (SDPARAM(isp, bus)->role & ISP_ROLE_TARGET) != 0;
1273         }
1274
1275         /*
1276          * Create the state pointer.
1277          * It should not already exist.
1278          */
1279         tptr = get_lun_statep(isp, bus, lun);
1280         if (tptr) {
1281                 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
1282                 goto done;
1283         }
1284         ccb->ccb_h.status = create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
1285         if (ccb->ccb_h.status != CAM_REQ_CMP) {
1286                 goto done;
1287         }
1288
1289         /*
1290          * We have a tricky maneuver to perform here.
1291          *
1292          * If target mode isn't already enabled here,
1293          * *and* our current role includes target mode,
1294          * we enable target mode here.
1295          *
1296          */
1297         ISP_GET_PC(isp, bus, tm_enabled, tm_enabled);
1298         if (tm_enabled == 0 && target_role != 0) {
1299                 if (isp_enable_target_mode(isp, bus)) {
1300                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1301                         destroy_lun_state(isp, tptr);
1302                         tptr = NULL;
1303                         goto done;
1304                 }
1305                 tm_enabled = 1;
1306         }
1307
1308         /*
1309          * Now check to see whether this bus is in target mode already.
1310          *
1311          * If not, a later role change into target mode will finish the job.
1312          */
1313         if (tm_enabled == 0) {
1314                 ISP_SET_PC(isp, bus, tm_enable_defer, 1);
1315                 ccb->ccb_h.status = CAM_REQ_CMP;
1316                 xpt_print(ccb->ccb_h.path, "Target Mode not enabled yet- lun enable deferred\n");
1317                 goto done1;
1318         }
1319
1320         /*
1321          * Enable the lun.
1322          */
1323         ccb->ccb_h.status = isp_enable_deferred(isp, bus, lun);
1324
1325 done:
1326         if (ccb->ccb_h.status != CAM_REQ_CMP)  {
1327                 if (tptr) {
1328                         destroy_lun_state(isp, tptr);
1329                         tptr = NULL;
1330                 }
1331         } else {
1332                 tptr->enabled = 1;
1333         }
1334 done1:
1335         if (tptr) {
1336                 rls_lun_statep(isp, tptr);
1337         }
1338
1339         /*
1340          * And we're outta here....
1341          */
1342         isp_tmunlk(isp);
1343         xpt_done(ccb);
1344 }
1345
1346 static cam_status
1347 isp_enable_deferred_luns(ispsoftc_t *isp, int bus)
1348 {
1349         tstate_t *tptr = NULL;
1350         struct tslist *lhp;
1351         int i, n;
1352
1353
1354         ISP_GET_PC(isp, bus, tm_enabled, i);
1355         if (i == 1) {
1356                 return (CAM_REQ_CMP);
1357         }
1358         ISP_GET_PC(isp, bus, tm_enable_defer, i);
1359         if (i == 0) {
1360                 return (CAM_REQ_CMP);
1361         }
1362         /*
1363          * If this succeeds, it will set tm_enable
1364          */
1365         if (isp_enable_target_mode(isp, bus)) {
1366                 return (CAM_REQ_CMP_ERR);
1367         }
1368         isp_tmlock(isp, "isp_enable_deferred_luns");
1369         for (n = i = 0; i < LUN_HASH_SIZE; i++) {
1370                 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
1371                 SLIST_FOREACH(tptr, lhp, next) {
1372                         tptr->hold++;
1373                         if (tptr->enabled == 0) {
1374                                 if (isp_enable_deferred(isp, bus, tptr->ts_lun) == CAM_REQ_CMP) {
1375                                         tptr->enabled = 1;
1376                                         n++;
1377                                 }
1378                         } else {
1379                                 n++;
1380                         }
1381                         tptr->hold--;
1382                 }
1383         }
1384         isp_tmunlk(isp);
1385         if (n == 0) {
1386                 return (CAM_REQ_CMP_ERR);
1387         }
1388         ISP_SET_PC(isp, bus, tm_enable_defer, 0);
1389         return (CAM_REQ_CMP);
1390 }
1391
1392 static cam_status
1393 isp_enable_deferred(ispsoftc_t *isp, int bus, lun_id_t lun)
1394 {
1395         cam_status status;
1396         int luns_already_enabled;
1397
1398         ISP_GET_PC(isp, bus, tm_luns_enabled, luns_already_enabled);
1399         isp_prt(isp, ISP_LOGTINFO, "%s: bus %d lun %jx luns_enabled %d", __func__, bus, (uintmax_t)lun, luns_already_enabled);
1400         if (IS_24XX(isp) || (IS_FC(isp) && luns_already_enabled)) {
1401                 status = CAM_REQ_CMP;
1402         } else {
1403                 int cmd_cnt, not_cnt;
1404
1405                 if (IS_23XX(isp)) {
1406                         cmd_cnt = DFLT_CMND_CNT;
1407                         not_cnt = DFLT_INOT_CNT;
1408                 } else {
1409                         cmd_cnt = 64;
1410                         not_cnt = 8;
1411                 }
1412                 status = CAM_REQ_INPROG;
1413                 isp->isp_osinfo.rptr = &status;
1414                 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun == CAM_LUN_WILDCARD? 0 : lun, cmd_cnt, not_cnt)) {
1415                         status = CAM_RESRC_UNAVAIL;
1416                 } else {
1417                         mtx_sleep(&status, &isp->isp_lock, PRIBIO, "isp_enable_deferred", 0);
1418                 }
1419                 isp->isp_osinfo.rptr = NULL;
1420         }
1421         if (status == CAM_REQ_CMP) {
1422                 ISP_SET_PC(isp, bus, tm_luns_enabled, 1);
1423                 isp_prt(isp, ISP_LOGCONFIG|ISP_LOGTINFO, "bus %d lun %jx now enabled for target mode", bus, (uintmax_t)lun);
1424         }
1425         return (status);
1426 }
1427
1428 static void
1429 isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
1430 {
1431         tstate_t *tptr = NULL;
1432         int bus;
1433         cam_status status;
1434         target_id_t target;
1435         lun_id_t lun;
1436
1437         bus = XS_CHANNEL(ccb);
1438         target = ccb->ccb_h.target_id;
1439         lun = ccb->ccb_h.target_lun;
1440         ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "disabling lun %u\n", lun);
1441         if (target != CAM_TARGET_WILDCARD && target != 0) {
1442                 ccb->ccb_h.status = CAM_TID_INVALID;
1443                 xpt_done(ccb);
1444                 return;
1445         }
1446
1447         if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
1448                 ccb->ccb_h.status = CAM_LUN_INVALID;
1449                 xpt_done(ccb);
1450                 return;
1451         }
1452
1453         if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
1454                 ccb->ccb_h.status = CAM_LUN_INVALID;
1455                 xpt_done(ccb);
1456                 return;
1457         }
1458
1459         /*
1460          * See if we're busy disabling a lun now.
1461          */
1462         isp_tmlock(isp, "isp_disable_lun");
1463         status = CAM_REQ_INPROG;
1464
1465         /*
1466          * Find the state pointer.
1467          */
1468         if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) {
1469                 status = CAM_PATH_INVALID;
1470                 goto done;
1471         }
1472
1473         /*
1474          * If we're a 24XX card, we're done.
1475          */
1476         if (IS_24XX(isp)) {
1477                 status = CAM_REQ_CMP;
1478                 goto done;
1479         }
1480
1481         /*
1482          * For SCC FW, we only deal with lun zero.
1483          */
1484         if (IS_FC(isp) && lun > 0) {
1485                 status = CAM_REQ_CMP;
1486                 goto done;
1487         }
1488         isp->isp_osinfo.rptr = &status;
1489         if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, 0, 0)) {
1490                 status = CAM_RESRC_UNAVAIL;
1491         } else {
1492                 mtx_sleep(ccb, &isp->isp_lock, PRIBIO, "isp_disable_lun", 0);
1493         }
1494         isp->isp_osinfo.rptr = NULL;
1495 done:
1496         if (status == CAM_REQ_CMP) {
1497                 tptr->enabled = 0;
1498                 /*
1499                  * If we have no more luns enabled for this bus,
1500                  * delete all tracked wwns for it (if we are FC), 
1501                  * and disable target mode.
1502                  */
1503                 if (is_any_lun_enabled(isp, bus) == 0) {
1504                         isp_del_all_wwn_entries(isp, bus);
1505                         if (isp_disable_target_mode(isp, bus)) {
1506                                 status = CAM_REQ_CMP_ERR;
1507                         }
1508                 }
1509         }
1510         ccb->ccb_h.status = status;
1511         if (status == CAM_REQ_CMP) {
1512                 destroy_lun_state(isp, tptr);
1513                 xpt_print(ccb->ccb_h.path, "lun now disabled for target mode\n");
1514         } else {
1515                 if (tptr)
1516                         rls_lun_statep(isp, tptr);
1517         }
1518         isp_tmunlk(isp);
1519         xpt_done(ccb);
1520 }
1521
1522 static int
1523 isp_enable_target_mode(ispsoftc_t *isp, int bus)
1524 {
1525         int tm_enabled;
1526
1527         ISP_GET_PC(isp, bus, tm_enabled, tm_enabled);
1528         if (tm_enabled != 0) {
1529                 return (0);
1530         }
1531         if (IS_SCSI(isp)) {
1532                 mbreg_t mbs;
1533                 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
1534                 mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
1535                 mbs.param[1] = ENABLE_TARGET_FLAG|ENABLE_TQING_FLAG;
1536                 mbs.param[2] = bus << 7;
1537                 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1538                         isp_prt(isp, ISP_LOGERR, "Unable to enable Target Role on Bus %d", bus);
1539                         return (EIO);
1540                 }
1541         }
1542         ISP_SET_PC(isp, bus, tm_enabled, 1);
1543         isp_prt(isp, ISP_LOGINFO, "Target Role enabled on Bus %d", bus);
1544         return (0);
1545 }
1546
1547 static int
1548 isp_disable_target_mode(ispsoftc_t *isp, int bus)
1549 {
1550         int tm_enabled;
1551
1552         ISP_GET_PC(isp, bus, tm_enabled, tm_enabled);
1553         if (tm_enabled == 0) {
1554                 return (0);
1555         }
1556         if (IS_SCSI(isp)) {
1557                 mbreg_t mbs;
1558                 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
1559                 mbs.param[2] = bus << 7;
1560                 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1561                         isp_prt(isp, ISP_LOGERR, "Unable to disable Target Role on Bus %d", bus);
1562                         return (EIO);
1563                 }
1564         }
1565         ISP_SET_PC(isp, bus, tm_enabled, 0);
1566         isp_prt(isp, ISP_LOGINFO, "Target Role disabled on Bus %d", bus);
1567         return (0);
1568 }
1569
1570 static void
1571 isp_ledone(ispsoftc_t *isp, lun_entry_t *lep)
1572 {
1573         uint32_t *rptr;
1574
1575         rptr = isp->isp_osinfo.rptr;
1576         if (lep->le_status != LUN_OK) {
1577                 isp_prt(isp, ISP_LOGERR, "ENABLE/MODIFY LUN returned 0x%x", lep->le_status);
1578                 if (rptr) {
1579                         *rptr = CAM_REQ_CMP_ERR;
1580                         wakeup_one(rptr);
1581                 }
1582         } else {
1583                 if (rptr) {
1584                         *rptr = CAM_REQ_CMP;
1585                         wakeup_one(rptr);
1586                 }
1587         }
1588 }
1589
1590 static void
1591 isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
1592 {
1593         int fctape, sendstatus, resid;
1594         tstate_t *tptr;
1595         fcparam *fcp;
1596         atio_private_data_t *atp;
1597         struct ccb_scsiio *cso;
1598         uint32_t dmaresult, handle, xfrlen, sense_length, tmp;
1599         uint8_t local[QENTRY_LEN];
1600
1601         tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
1602         if (tptr == NULL) {
1603                 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
1604                 if (tptr == NULL) {
1605                         isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find tstate pointer", __func__, ccb->csio.tag_id);
1606                         ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1607                         xpt_done(ccb);
1608                         return;
1609                 }
1610         }
1611         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,
1612             (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0, ((ccb->ccb_h.flags & CAM_SEND_SENSE)? ccb->csio.sense_len : 0));
1613
1614         switch (how) {
1615         case FROM_TIMER:
1616         case FROM_CAM:
1617                 /*
1618                  * Insert at the tail of the list, if any, waiting CTIO CCBs
1619                  */
1620                 TAILQ_INSERT_TAIL(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 
1621                 break;
1622         case FROM_SRR:
1623         case FROM_CTIO_DONE:
1624                 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 
1625                 break;
1626         }
1627
1628         while (TAILQ_FIRST(&tptr->waitq) != NULL) {
1629                 ccb = (union ccb *) TAILQ_FIRST(&tptr->waitq);
1630                 TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
1631
1632                 cso = &ccb->csio;
1633                 xfrlen = cso->dxfer_len;
1634                 if (xfrlen == 0) {
1635                         if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) {
1636                                 ISP_PATH_PRT(isp, ISP_LOGERR, ccb->ccb_h.path, "a data transfer length of zero but no status to send is wrong\n");
1637                                 ccb->ccb_h.status = CAM_REQ_INVALID;
1638                                 xpt_done(ccb);
1639                                 continue;
1640                         }
1641                 }
1642
1643                 atp = isp_find_atpd(isp, tptr, cso->tag_id);
1644                 if (atp == NULL) {
1645                         isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find private data adjunct in %s", __func__, cso->tag_id, __func__);
1646                         isp_dump_atpd(isp, tptr);
1647                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1648                         xpt_done(ccb);
1649                         continue;
1650                 }
1651
1652                 /*
1653                  * Is this command a dead duck?
1654                  */
1655                 if (atp->dead) {
1656                         isp_prt(isp, ISP_LOGERR, "%s: [0x%x] not sending a CTIO for a dead command", __func__, cso->tag_id);
1657                         ccb->ccb_h.status = CAM_REQ_ABORTED;
1658                         xpt_done(ccb);
1659                         continue;
1660                 }
1661
1662                 /*
1663                  * Check to make sure we're still in target mode.
1664                  */
1665                 fcp = FCPARAM(isp, XS_CHANNEL(ccb));
1666                 if ((fcp->role & ISP_ROLE_TARGET) == 0) {
1667                         isp_prt(isp, ISP_LOGERR, "%s: [0x%x] stopping sending a CTIO because we're no longer in target mode", __func__, cso->tag_id);
1668                         ccb->ccb_h.status = CAM_PROVIDE_FAIL;
1669                         xpt_done(ccb);
1670                         continue;
1671                 }
1672
1673                 /*
1674                  * We're only handling ATPD_CCB_OUTSTANDING outstanding CCB at a time (one of which
1675                  * could be split into two CTIOs to split data and status).
1676                  */
1677                 if (atp->ctcnt >= ATPD_CCB_OUTSTANDING) {
1678                         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);
1679                         TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 
1680                         break;
1681                 }
1682
1683                 /*
1684                  * Does the initiator expect FC-Tape style responses?
1685                  */
1686                 if ((atp->word3 & PRLI_WD3_RETRY) && fcp->fctape_enabled) {
1687                         fctape = 1;
1688                 } else {
1689                         fctape = 0;
1690                 }
1691
1692                 /*
1693                  * If we already did the data xfer portion of a CTIO that sends data
1694                  * and status, don't do it again and do the status portion now.
1695                  */
1696                 if (atp->sendst) {
1697                         isp_prt(isp, ISP_LOGTINFO, "[0x%x] now sending synthesized status orig_dl=%u xfered=%u bit=%u",
1698                             cso->tag_id, atp->orig_datalen, atp->bytes_xfered, atp->bytes_in_transit);
1699                         xfrlen = 0;     /* we already did the data transfer */
1700                         atp->sendst = 0;
1701                 }
1702                 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1703                         sendstatus = 1;
1704                 } else {
1705                         sendstatus = 0;
1706                 }
1707
1708                 if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
1709                         KASSERT((sendstatus != 0), ("how can you have CAM_SEND_SENSE w/o CAM_SEND_STATUS?"));
1710                         /*
1711                          * Sense length is not the entire sense data structure size. Periph
1712                          * drivers don't seem to be setting sense_len to reflect the actual
1713                          * size. We'll peek inside to get the right amount.
1714                          */
1715                         sense_length = cso->sense_len;
1716
1717                         /*
1718                          * This 'cannot' happen
1719                          */
1720                         if (sense_length > (XCMD_SIZE - MIN_FCP_RESPONSE_SIZE)) {
1721                                 sense_length = XCMD_SIZE - MIN_FCP_RESPONSE_SIZE;
1722                         }
1723                 } else {
1724                         sense_length = 0;
1725                 }
1726
1727                 memset(local, 0, QENTRY_LEN);
1728
1729                 /*
1730                  * Check for overflow
1731                  */
1732                 tmp = atp->bytes_xfered + atp->bytes_in_transit + xfrlen;
1733                 if (tmp > atp->orig_datalen) {
1734                         isp_prt(isp, ISP_LOGERR, "%s: [0x%x] data overflow by %u bytes", __func__, cso->tag_id, tmp - atp->orig_datalen);
1735                         ccb->ccb_h.status = CAM_DATA_RUN_ERR;
1736                         xpt_done(ccb);
1737                         continue;
1738                 }
1739
1740                 if (IS_24XX(isp)) {
1741                         ct7_entry_t *cto = (ct7_entry_t *) local;
1742
1743                         cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
1744                         cto->ct_header.rqs_entry_count = 1;
1745                         cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM;
1746                         ATPD_SET_SEQNO(cto, atp);
1747                         cto->ct_nphdl = atp->nphdl;
1748                         cto->ct_rxid = atp->tag;
1749                         cto->ct_iid_lo = atp->portid;
1750                         cto->ct_iid_hi = atp->portid >> 16;
1751                         cto->ct_oxid = atp->oxid;
1752                         cto->ct_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(ccb));
1753                         cto->ct_timeout = 120;
1754                         cto->ct_flags = atp->tattr << CT7_TASK_ATTR_SHIFT;
1755
1756                         /*
1757                          * Mode 1, status, no data. Only possible when we are sending status, have
1758                          * no data to transfer, and any sense data can fit into a ct7_entry_t.
1759                          *
1760                          * Mode 2, status, no data. We have to use this in the case that
1761                          * the sense data won't fit into a ct7_entry_t.
1762                          *
1763                          */
1764                         if (sendstatus && xfrlen == 0) {
1765                                 cto->ct_flags |= CT7_SENDSTATUS | CT7_NO_DATA;
1766                                 resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit;
1767                                 if (sense_length <= MAXRESPLEN_24XX) {
1768                                         if (resid < 0) {
1769                                                 cto->ct_resid = -resid;
1770                                         } else if (resid > 0) {
1771                                                 cto->ct_resid = resid;
1772                                         }
1773                                         cto->ct_flags |= CT7_FLAG_MODE1;
1774                                         cto->ct_scsi_status = cso->scsi_status;
1775                                         if (resid < 0) {
1776                                                 cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8);
1777                                         } else if (resid > 0) {
1778                                                 cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8);
1779                                         }
1780                                         if (fctape) {
1781                                                 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF;
1782                                         }
1783                                         if (sense_length) {
1784                                                 cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8);
1785                                                 cto->rsp.m1.ct_resplen = cto->ct_senselen = sense_length;
1786                                                 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length);
1787                                         }
1788                                 } else {
1789                                         bus_addr_t addr;
1790                                         char buf[XCMD_SIZE];
1791                                         fcp_rsp_iu_t *rp;
1792
1793                                         if (atp->ests == NULL) {
1794                                                 atp->ests = isp_get_ecmd(isp);
1795                                                 if (atp->ests == NULL) {
1796                                                         TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 
1797                                                         break;
1798                                                 }
1799                                         }
1800                                         memset(buf, 0, sizeof (buf));
1801                                         rp = (fcp_rsp_iu_t *)buf;
1802                                         if (fctape) {
1803                                                 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF;
1804                                                 rp->fcp_rsp_bits |= FCP_CONF_REQ;
1805                                         }
1806                                         cto->ct_flags |= CT7_FLAG_MODE2;
1807                                         rp->fcp_rsp_scsi_status = cso->scsi_status;
1808                                         if (resid < 0) {
1809                                                 rp->fcp_rsp_resid = -resid;
1810                                                 rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW;
1811                                         } else if (resid > 0) {
1812                                                 rp->fcp_rsp_resid = resid;
1813                                                 rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW;
1814                                         }
1815                                         if (sense_length) {
1816                                                 rp->fcp_rsp_snslen = sense_length;
1817                                                 cto->ct_senselen = sense_length;
1818                                                 rp->fcp_rsp_bits |= FCP_SNSLEN_VALID;
1819                                                 isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1820                                                 memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length);
1821                                         } else {
1822                                                 isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1823                                         }
1824                                         if (isp->isp_dblev & ISP_LOGTDEBUG1) {
1825                                                 isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests);
1826                                         }
1827                                         addr = isp->isp_osinfo.ecmd_dma;
1828                                         addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE);
1829                                         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,
1830                                             (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length);
1831                                         cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length;
1832                                         cto->rsp.m2.ct_fcp_rsp_iudata.ds_base = DMA_LO32(addr);
1833                                         cto->rsp.m2.ct_fcp_rsp_iudata.ds_basehi = DMA_HI32(addr);
1834                                         cto->rsp.m2.ct_fcp_rsp_iudata.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length;
1835                                 }
1836                                 if (sense_length) {
1837                                         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__,
1838                                             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,
1839                                             cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]);
1840                                 } else {
1841                                         isp_prt(isp, ISP_LOGDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d", __func__,
1842                                             cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, cto->ct_resid);
1843                                 }
1844                                 atp->state = ATPD_STATE_LAST_CTIO;
1845                         }
1846
1847                         /*
1848                          * Mode 0 data transfers, *possibly* with status.
1849                          */
1850                         if (xfrlen != 0) {
1851                                 cto->ct_flags |= CT7_FLAG_MODE0;
1852                                 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1853                                         cto->ct_flags |= CT7_DATA_IN;
1854                                 } else {
1855                                         cto->ct_flags |= CT7_DATA_OUT;
1856                                 }
1857
1858                                 cto->rsp.m0.reloff = atp->bytes_xfered + atp->bytes_in_transit;
1859                                 cto->rsp.m0.ct_xfrlen = xfrlen;
1860
1861 #ifdef  DEBUG
1862                                 if (ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame && xfrlen > ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame) {
1863                                         isp_prt(isp, ISP_LOGWARN, "%s: truncating data frame with xfrlen %d to %d", __func__, xfrlen, xfrlen - (xfrlen >> 2));
1864                                         ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame = 0;
1865                                         cto->rsp.m0.ct_xfrlen -= xfrlen >> 2;
1866                                 }
1867 #endif
1868                                 if (sendstatus) {
1869                                         resid = atp->orig_datalen - atp->bytes_xfered - xfrlen;
1870                                         if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /* && fctape == 0 */) {
1871                                                 cto->ct_flags |= CT7_SENDSTATUS;
1872                                                 atp->state = ATPD_STATE_LAST_CTIO;
1873                                                 if (fctape) {
1874                                                         cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF;
1875                                                 }
1876                                         } else {
1877                                                 atp->sendst = 1;        /* send status later */
1878                                                 cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM;
1879                                                 atp->state = ATPD_STATE_CTIO;
1880                                         }
1881                                 } else {
1882                                         atp->state = ATPD_STATE_CTIO;
1883                                 }
1884                                 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__,
1885                                     cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, xfrlen, atp->bytes_xfered);
1886                         }
1887                 } else if (IS_FC(isp)) {
1888                         ct2_entry_t *cto = (ct2_entry_t *) local;
1889
1890                         if (isp->isp_osinfo.sixtyfourbit)
1891                                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO3;
1892                         else
1893                                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
1894                         cto->ct_header.rqs_entry_count = 1;
1895                         cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM;
1896                         ATPD_SET_SEQNO(cto, atp);
1897                         if (ISP_CAP_2KLOGIN(isp) == 0) {
1898                                 ((ct2e_entry_t *)cto)->ct_iid = cso->init_id;
1899                         } else {
1900                                 cto->ct_iid = cso->init_id;
1901                                 if (ISP_CAP_SCCFW(isp) == 0) {
1902                                         cto->ct_lun = ccb->ccb_h.target_lun;
1903                                 }
1904                         }
1905                         cto->ct_timeout = 10;
1906                         cto->ct_rxid = cso->tag_id;
1907
1908                         /*
1909                          * Mode 1, status, no data. Only possible when we are sending status, have
1910                          * no data to transfer, and the sense length can fit in the ct7_entry.
1911                          *
1912                          * Mode 2, status, no data. We have to use this in the case the response
1913                          * length won't fit into a ct2_entry_t.
1914                          *
1915                          * We'll fill out this structure with information as if this were a
1916                          * Mode 1. The hardware layer will create the Mode 2 FCP RSP IU as
1917                          * needed based upon this.
1918                          */
1919                         if (sendstatus && xfrlen == 0) {
1920                                 cto->ct_flags |= CT2_SENDSTATUS | CT2_NO_DATA;
1921                                 resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit;
1922                                 if (sense_length <= MAXRESPLEN) {
1923                                         if (resid < 0) {
1924                                                 cto->ct_resid = -resid;
1925                                         } else if (resid > 0) {
1926                                                 cto->ct_resid = resid;
1927                                         }
1928                                         cto->ct_flags |= CT2_FLAG_MODE1;
1929                                         cto->rsp.m1.ct_scsi_status = cso->scsi_status;
1930                                         if (resid < 0) {
1931                                                 cto->rsp.m1.ct_scsi_status |= CT2_DATA_OVER;
1932                                         } else if (resid > 0) {
1933                                                 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
1934                                         }
1935                                         if (fctape) {
1936                                                 cto->ct_flags |= CT2_CONFIRM;
1937                                         }
1938                                         if (sense_length) {
1939                                                 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
1940                                                 cto->rsp.m1.ct_resplen = cto->rsp.m1.ct_senselen = sense_length;
1941                                                 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length);
1942                                         }
1943                                 } else {
1944                                         bus_addr_t addr;
1945                                         char buf[XCMD_SIZE];
1946                                         fcp_rsp_iu_t *rp;
1947
1948                                         if (atp->ests == NULL) {
1949                                                 atp->ests = isp_get_ecmd(isp);
1950                                                 if (atp->ests == NULL) {
1951                                                         TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 
1952                                                         break;
1953                                                 }
1954                                         }
1955                                         memset(buf, 0, sizeof (buf));
1956                                         rp = (fcp_rsp_iu_t *)buf;
1957                                         if (fctape) {
1958                                                 cto->ct_flags |= CT2_CONFIRM;
1959                                                 rp->fcp_rsp_bits |= FCP_CONF_REQ;
1960                                         }
1961                                         cto->ct_flags |= CT2_FLAG_MODE2;
1962                                         rp->fcp_rsp_scsi_status = cso->scsi_status;
1963                                         if (resid < 0) {
1964                                                 rp->fcp_rsp_resid = -resid;
1965                                                 rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW;
1966                                         } else if (resid > 0) {
1967                                                 rp->fcp_rsp_resid = resid;
1968                                                 rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW;
1969                                         }
1970                                         if (sense_length) {
1971                                                 rp->fcp_rsp_snslen = sense_length;
1972                                                 rp->fcp_rsp_bits |= FCP_SNSLEN_VALID;
1973                                                 isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1974                                                 memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length);
1975                                         } else {
1976                                                 isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1977                                         }
1978                                         if (isp->isp_dblev & ISP_LOGTDEBUG1) {
1979                                                 isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests);
1980                                         }
1981                                         addr = isp->isp_osinfo.ecmd_dma;
1982                                         addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE);
1983                                         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,
1984                                             (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length);
1985                                         cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length;
1986                                         if (isp->isp_osinfo.sixtyfourbit) {
1987                                                 cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_base = DMA_LO32(addr);
1988                                                 cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_basehi = DMA_HI32(addr);
1989                                                 cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length;
1990                                         } else {
1991                                                 cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_base = DMA_LO32(addr);
1992                                                 cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length;
1993                                         }
1994                                 }
1995                                 if (sense_length) {
1996                                         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__,
1997                                             cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid,
1998                                             cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]);
1999                                 } else {
2000                                         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,
2001                                             ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid);
2002                                 }
2003                                 atp->state = ATPD_STATE_LAST_CTIO;
2004                         }
2005
2006                         if (xfrlen != 0) {
2007                                 cto->ct_flags |= CT2_FLAG_MODE0;
2008                                 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2009                                         cto->ct_flags |= CT2_DATA_IN;
2010                                 } else {
2011                                         cto->ct_flags |= CT2_DATA_OUT;
2012                                 }
2013
2014                                 cto->ct_reloff = atp->bytes_xfered + atp->bytes_in_transit;
2015                                 cto->rsp.m0.ct_xfrlen = xfrlen;
2016
2017                                 if (sendstatus) {
2018                                         resid = atp->orig_datalen - atp->bytes_xfered - xfrlen;
2019                                         if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /*&& fctape == 0*/) {
2020                                                 cto->ct_flags |= CT2_SENDSTATUS;
2021                                                 atp->state = ATPD_STATE_LAST_CTIO;
2022                                                 if (fctape) {
2023                                                         cto->ct_flags |= CT2_CONFIRM;
2024                                                 }
2025                                         } else {
2026                                                 atp->sendst = 1;        /* send status later */
2027                                                 cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM;
2028                                                 atp->state = ATPD_STATE_CTIO;
2029                                         }
2030                                 } else {
2031                                         atp->state = ATPD_STATE_CTIO;
2032                                 }
2033                         }
2034                         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,
2035                             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);
2036                 } else {
2037                         ct_entry_t *cto = (ct_entry_t *) local;
2038
2039                         cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
2040                         cto->ct_header.rqs_entry_count = 1;
2041                         cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM;
2042                         ATPD_SET_SEQNO(cto, atp);
2043                         cto->ct_iid = cso->init_id;
2044                         cto->ct_iid |= XS_CHANNEL(ccb) << 7;
2045                         cto->ct_tgt = ccb->ccb_h.target_id;
2046                         cto->ct_lun = ccb->ccb_h.target_lun;
2047                         cto->ct_fwhandle = cso->tag_id;
2048                         if (atp->rxid) {
2049                                 cto->ct_tag_val = atp->rxid;
2050                                 cto->ct_flags |= CT_TQAE;
2051                         }
2052                         if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) {
2053                                 cto->ct_flags |= CT_NODISC;
2054                         }
2055                         if (cso->dxfer_len == 0) {
2056                                 cto->ct_flags |= CT_NO_DATA;
2057                         } else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2058                                 cto->ct_flags |= CT_DATA_IN;
2059                         } else {
2060                                 cto->ct_flags |= CT_DATA_OUT;
2061                         }
2062                         if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
2063                                 cto->ct_flags |= CT_SENDSTATUS|CT_CCINCR;
2064                                 cto->ct_scsi_status = cso->scsi_status;
2065                                 cto->ct_resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit - xfrlen;
2066                                 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO[%x] seq %u nc %d scsi status %x resid %d tag_id %x", __func__,
2067                                     cto->ct_fwhandle, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), cso->scsi_status, cso->resid, cso->tag_id);
2068                         }
2069                         ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
2070                         cto->ct_timeout = 10;
2071                 }
2072
2073                 if (isp_get_pcmd(isp, ccb)) {
2074                         ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "out of PCMDs\n");
2075                         TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 
2076                         break;
2077                 }
2078                 if (isp_allocate_xs_tgt(isp, ccb, &handle)) {
2079                         ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__);
2080                         TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 
2081                         isp_free_pcmd(isp, ccb);
2082                         break;
2083                 }
2084                 atp->bytes_in_transit += xfrlen;
2085                 PISP_PCMD(ccb)->datalen = xfrlen;
2086
2087
2088                 /*
2089                  * Call the dma setup routines for this entry (and any subsequent
2090                  * CTIOs) if there's data to move, and then tell the f/w it's got
2091                  * new things to play with. As with isp_start's usage of DMA setup,
2092                  * any swizzling is done in the machine dependent layer. Because
2093                  * of this, we put the request onto the queue area first in native
2094                  * format.
2095                  */
2096
2097                 if (IS_24XX(isp)) {
2098                         ct7_entry_t *cto = (ct7_entry_t *) local;
2099                         cto->ct_syshandle = handle;
2100                 } else if (IS_FC(isp)) {
2101                         ct2_entry_t *cto = (ct2_entry_t *) local;
2102                         cto->ct_syshandle = handle;
2103                 } else {
2104                         ct_entry_t *cto = (ct_entry_t *) local;
2105                         cto->ct_syshandle = handle;
2106                 }
2107
2108                 dmaresult = ISP_DMASETUP(isp, cso, (ispreq_t *) local);
2109                 if (dmaresult != CMD_QUEUED) {
2110                         isp_destroy_tgt_handle(isp, handle);
2111                         isp_free_pcmd(isp, ccb);
2112                         if (dmaresult == CMD_EAGAIN) {
2113                                 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 
2114                                 break;
2115                         }
2116                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2117                         xpt_done(ccb);
2118                         continue;
2119                 }
2120                 isp->isp_nactive++;
2121                 ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED;
2122                 if (xfrlen) {
2123                         ccb->ccb_h.spriv_field0 = atp->bytes_xfered;
2124                 } else {
2125                         ccb->ccb_h.spriv_field0 = ~0;
2126                 }
2127                 atp->ctcnt++;
2128                 atp->seqno++;
2129         }
2130         rls_lun_statep(isp, tptr);
2131 }
2132
2133 static void
2134 isp_refire_putback_atio(void *arg)
2135 {
2136         union ccb *ccb = arg;
2137
2138         ISP_ASSERT_LOCKED((ispsoftc_t *)XS_ISP(ccb));
2139         isp_target_putback_atio(ccb);
2140 }
2141
2142 static void
2143 isp_refire_notify_ack(void *arg)
2144 {
2145         isp_tna_t *tp  = arg;
2146         ispsoftc_t *isp = tp->isp;
2147
2148         ISP_ASSERT_LOCKED(isp);
2149         if (isp_notify_ack(isp, tp->not)) {
2150                 callout_schedule(&tp->timer, 5);
2151         } else {
2152                 free(tp, M_DEVBUF);
2153         }
2154 }
2155
2156
2157 static void
2158 isp_target_putback_atio(union ccb *ccb)
2159 {
2160         ispsoftc_t *isp;
2161         struct ccb_scsiio *cso;
2162         void *qe;
2163
2164         isp = XS_ISP(ccb);
2165
2166         qe = isp_getrqentry(isp);
2167         if (qe == NULL) {
2168                 xpt_print(ccb->ccb_h.path,
2169                     "%s: Request Queue Overflow\n", __func__);
2170                 callout_reset(&PISP_PCMD(ccb)->wdog, 10,
2171                     isp_refire_putback_atio, ccb);
2172                 return;
2173         }
2174         memset(qe, 0, QENTRY_LEN);
2175         cso = &ccb->csio;
2176         if (IS_FC(isp)) {
2177                 at2_entry_t local, *at = &local;
2178                 ISP_MEMZERO(at, sizeof (at2_entry_t));
2179                 at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
2180                 at->at_header.rqs_entry_count = 1;
2181                 if (ISP_CAP_SCCFW(isp)) {
2182                         at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
2183                 } else {
2184                         at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
2185                 }
2186                 at->at_status = CT_OK;
2187                 at->at_rxid = cso->tag_id;
2188                 at->at_iid = cso->ccb_h.target_id;
2189                 isp_put_atio2(isp, at, qe);
2190         } else {
2191                 at_entry_t local, *at = &local;
2192                 ISP_MEMZERO(at, sizeof (at_entry_t));
2193                 at->at_header.rqs_entry_type = RQSTYPE_ATIO;
2194                 at->at_header.rqs_entry_count = 1;
2195                 at->at_iid = cso->init_id;
2196                 at->at_iid |= XS_CHANNEL(ccb) << 7;
2197                 at->at_tgt = cso->ccb_h.target_id;
2198                 at->at_lun = cso->ccb_h.target_lun;
2199                 at->at_status = CT_OK;
2200                 at->at_tag_val = AT_GET_TAG(cso->tag_id);
2201                 at->at_handle = AT_GET_HANDLE(cso->tag_id);
2202                 isp_put_atio(isp, at, qe);
2203         }
2204         ISP_TDQE(isp, "isp_target_putback_atio", isp->isp_reqidx, qe);
2205         ISP_SYNC_REQUEST(isp);
2206         isp_complete_ctio(ccb);
2207 }
2208
2209 static void
2210 isp_complete_ctio(union ccb *ccb)
2211 {
2212         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
2213                 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2214                 xpt_done(ccb);
2215         }
2216 }
2217
2218 /*
2219  * Handle ATIO stuff that the generic code can't.
2220  * This means handling CDBs.
2221  */
2222
2223 static void
2224 isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep)
2225 {
2226         tstate_t *tptr;
2227         int status, bus;
2228         struct ccb_accept_tio *atiop;
2229         atio_private_data_t *atp;
2230
2231         /*
2232          * The firmware status (except for the QLTM_SVALID bit)
2233          * indicates why this ATIO was sent to us.
2234          *
2235          * If QLTM_SVALID is set, the firmware has recommended Sense Data.
2236          *
2237          * If the DISCONNECTS DISABLED bit is set in the flags field,
2238          * we're still connected on the SCSI bus.
2239          */
2240         status = aep->at_status;
2241         if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
2242                 /*
2243                  * Bus Phase Sequence error. We should have sense data
2244                  * suggested by the f/w. I'm not sure quite yet what
2245                  * to do about this for CAM.
2246                  */
2247                 isp_prt(isp, ISP_LOGWARN, "PHASE ERROR");
2248                 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
2249                 return;
2250         }
2251         if ((status & ~QLTM_SVALID) != AT_CDB) {
2252                 isp_prt(isp, ISP_LOGWARN, "bad atio (0x%x) leaked to platform", status);
2253                 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
2254                 return;
2255         }
2256
2257         bus = GET_BUS_VAL(aep->at_iid);
2258         tptr = get_lun_statep(isp, bus, aep->at_lun);
2259         if (tptr == NULL) {
2260                 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
2261                 if (tptr == NULL) {
2262                         /*
2263                          * Because we can't autofeed sense data back with
2264                          * a command for parallel SCSI, we can't give back
2265                          * a CHECK CONDITION. We'll give back a BUSY status
2266                          * instead. This works out okay because the only
2267                          * time we should, in fact, get this, is in the
2268                          * case that somebody configured us without the
2269                          * blackhole driver, so they get what they deserve.
2270                          */
2271                         isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
2272                         return;
2273                 }
2274         }
2275
2276         atp = isp_get_atpd(isp, tptr, aep->at_handle);
2277         atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
2278         if (atiop == NULL || atp == NULL) {
2279                 /*
2280                  * Because we can't autofeed sense data back with
2281                  * a command for parallel SCSI, we can't give back
2282                  * a CHECK CONDITION. We'll give back a QUEUE FULL status
2283                  * instead. This works out okay because the only time we
2284                  * should, in fact, get this, is in the case that we've
2285                  * run out of ATIOS.
2286                  */
2287                 xpt_print(tptr->owner, "no %s for lun %d from initiator %d\n", (atp == NULL && atiop == NULL)? "ATIOs *or* ATPS" :
2288                     ((atp == NULL)? "ATPs" : "ATIOs"), aep->at_lun, aep->at_iid);
2289                 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
2290                 if (atp) {
2291                         isp_put_atpd(isp, tptr, atp);
2292                 }
2293                 rls_lun_statep(isp, tptr);
2294                 return;
2295         }
2296         atp->rxid = aep->at_tag_val;
2297         atp->state = ATPD_STATE_ATIO;
2298         SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
2299         tptr->atio_count--;
2300         ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO count now %d\n", tptr->atio_count);
2301         atiop->ccb_h.target_id = aep->at_tgt;
2302         atiop->ccb_h.target_lun = aep->at_lun;
2303         if (aep->at_flags & AT_NODISC) {
2304                 atiop->ccb_h.flags |= CAM_DIS_DISCONNECT;
2305         } else {
2306                 atiop->ccb_h.flags &= ~CAM_DIS_DISCONNECT;
2307         }
2308
2309         if (status & QLTM_SVALID) {
2310                 size_t amt = ISP_MIN(QLTM_SENSELEN, sizeof (atiop->sense_data));
2311                 atiop->sense_len = amt;
2312                 ISP_MEMCPY(&atiop->sense_data, aep->at_sense, amt);
2313         } else {
2314                 atiop->sense_len = 0;
2315         }
2316
2317         atiop->init_id = GET_IID_VAL(aep->at_iid);
2318         atiop->cdb_len = aep->at_cdblen;
2319         ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
2320         atiop->ccb_h.status = CAM_CDB_RECVD;
2321         /*
2322          * Construct a tag 'id' based upon tag value (which may be 0..255)
2323          * and the handle (which we have to preserve).
2324          */
2325         atiop->tag_id = atp->tag;
2326         if (aep->at_flags & AT_TQAE) {
2327                 atiop->tag_action = aep->at_tag_type;
2328                 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
2329         }
2330         atp->orig_datalen = 0;
2331         atp->bytes_xfered = 0;
2332         atp->lun = aep->at_lun;
2333         atp->nphdl = aep->at_iid;
2334         atp->portid = PORT_NONE;
2335         atp->oxid = 0;
2336         atp->cdb0 = atiop->cdb_io.cdb_bytes[0];
2337         atp->tattr = aep->at_tag_type;
2338         atp->state = ATPD_STATE_CAM;
2339         isp_prt(isp, ISP_LOGTDEBUG0, "ATIO[0x%x] CDB=0x%x lun %d", aep->at_tag_val, atp->cdb0, atp->lun);
2340         rls_lun_statep(isp, tptr);
2341 }
2342
2343 static void
2344 isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
2345 {
2346         lun_id_t lun;
2347         fcportdb_t *lp;
2348         tstate_t *tptr;
2349         struct ccb_accept_tio *atiop;
2350         uint16_t nphdl;
2351         atio_private_data_t *atp;
2352         inot_private_data_t *ntp;
2353
2354         /*
2355          * The firmware status (except for the QLTM_SVALID bit)
2356          * indicates why this ATIO was sent to us.
2357          *
2358          * If QLTM_SVALID is set, the firmware has recommended Sense Data.
2359          */
2360         if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
2361                 isp_prt(isp, ISP_LOGWARN, "bogus atio (0x%x) leaked to platform", aep->at_status);
2362                 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
2363                 return;
2364         }
2365
2366         if (ISP_CAP_SCCFW(isp)) {
2367                 lun = aep->at_scclun;
2368         } else {
2369                 lun = aep->at_lun;
2370         }
2371         if (ISP_CAP_2KLOGIN(isp)) {
2372                 nphdl = ((at2e_entry_t *)aep)->at_iid;
2373         } else {
2374                 nphdl = aep->at_iid;
2375         }
2376         tptr = get_lun_statep(isp, 0, lun);
2377         if (tptr == NULL) {
2378                 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
2379                 if (tptr == NULL) {
2380                         isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %jx or wildcard", __func__, aep->at_rxid, (uintmax_t)lun);
2381                         if (lun == 0) {
2382                                 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
2383                         } else {
2384                                 isp_endcmd(isp, aep, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
2385                         }
2386                         return;
2387                 }
2388         }
2389
2390         /*
2391          * Start any commands pending resources first.
2392          */
2393         if (tptr->restart_queue) {
2394                 inot_private_data_t *restart_queue = tptr->restart_queue;
2395                 tptr->restart_queue = NULL;
2396                 while (restart_queue) {
2397                         ntp = restart_queue;
2398                         restart_queue = ntp->rd.nt.nt_hba;
2399                         isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid);
2400                         isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data);
2401                         isp_put_ntpd(isp, tptr, ntp);
2402                         /*
2403                          * If a recursion caused the restart queue to start to fill again,
2404                          * stop and splice the new list on top of the old list and restore
2405                          * it and go to noresrc.
2406                          */
2407                         if (tptr->restart_queue) {
2408                                 ntp = tptr->restart_queue;
2409                                 tptr->restart_queue = restart_queue;
2410                                 while (restart_queue->rd.nt.nt_hba) {
2411                                         restart_queue = restart_queue->rd.nt.nt_hba;
2412                                 }
2413                                 restart_queue->rd.nt.nt_hba = ntp;
2414                                 goto noresrc;
2415                         }
2416                 }
2417         }
2418
2419         atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
2420         if (atiop == NULL) {
2421                 goto noresrc;
2422         }
2423
2424         atp = isp_get_atpd(isp, tptr, aep->at_rxid);
2425         if (atp == NULL) {
2426                 goto noresrc;
2427         }
2428
2429         atp->state = ATPD_STATE_ATIO;
2430         SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
2431         tptr->atio_count--;
2432         isp_prt(isp, ISP_LOGTDEBUG2, "Take FREE ATIO count now %d", tptr->atio_count);
2433         atiop->ccb_h.target_id = FCPARAM(isp, 0)->isp_loopid;
2434         atiop->ccb_h.target_lun = lun;
2435
2436         /*
2437          * We don't get 'suggested' sense data as we do with SCSI cards.
2438          */
2439         atiop->sense_len = 0;
2440         if (ISP_CAP_2KLOGIN(isp)) {
2441                 /*
2442                  * NB: We could not possibly have 2K logins if we
2443                  * NB: also did not have SCC FW.
2444                  */
2445                 atiop->init_id = ((at2e_entry_t *)aep)->at_iid;
2446         } else {
2447                 atiop->init_id = aep->at_iid;
2448         }
2449
2450         /*
2451          * If we're not in the port database, add ourselves.
2452          */
2453         if (!IS_2100(isp) && isp_find_pdb_by_loopid(isp, 0, atiop->init_id, &lp) == 0) {
2454                 uint64_t iid =
2455                         (((uint64_t) aep->at_wwpn[0]) << 48) |
2456                         (((uint64_t) aep->at_wwpn[1]) << 32) |
2457                         (((uint64_t) aep->at_wwpn[2]) << 16) |
2458                         (((uint64_t) aep->at_wwpn[3]) <<  0);
2459                 /*
2460                  * However, make sure we delete ourselves if otherwise
2461                  * we were there but at a different loop id.
2462                  */
2463                 if (isp_find_pdb_by_wwn(isp, 0, iid, &lp)) {
2464                         isp_del_wwn_entry(isp, 0, iid, lp->handle, lp->portid);
2465                 }
2466                 isp_add_wwn_entry(isp, 0, iid, atiop->init_id, PORT_ANY, 0);
2467         }
2468         atiop->cdb_len = ATIO2_CDBLEN;
2469         ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
2470         atiop->ccb_h.status = CAM_CDB_RECVD;
2471         atiop->tag_id = atp->tag;
2472         switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
2473         case ATIO2_TC_ATTR_SIMPLEQ:
2474                 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
2475                 atiop->tag_action = MSG_SIMPLE_Q_TAG;
2476                 break;
2477         case ATIO2_TC_ATTR_HEADOFQ:
2478                 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
2479                 atiop->tag_action = MSG_HEAD_OF_Q_TAG;
2480                 break;
2481         case ATIO2_TC_ATTR_ORDERED:
2482                 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
2483                 atiop->tag_action = MSG_ORDERED_Q_TAG;
2484                 break;
2485         case ATIO2_TC_ATTR_ACAQ:                /* ?? */
2486         case ATIO2_TC_ATTR_UNTAGGED:
2487         default:
2488                 atiop->tag_action = 0;
2489                 break;
2490         }
2491
2492         atp->orig_datalen = aep->at_datalen;
2493         atp->bytes_xfered = 0;
2494         atp->lun = lun;
2495         atp->nphdl = atiop->init_id;
2496         atp->sid = PORT_ANY;
2497         atp->oxid = aep->at_oxid;
2498         atp->cdb0 = aep->at_cdb[0];
2499         atp->tattr = aep->at_taskflags & ATIO2_TC_ATTR_MASK;
2500         atp->state = ATPD_STATE_CAM;
2501         xpt_done((union ccb *)atiop);
2502         isp_prt(isp, ISP_LOGTDEBUG0, "ATIO2[0x%x] CDB=0x%x lun %jx datalen %u", aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen);
2503         rls_lun_statep(isp, tptr);
2504         return;
2505 noresrc:
2506         ntp = isp_get_ntpd(isp, tptr);
2507         if (ntp == NULL) {
2508                 rls_lun_statep(isp, tptr);
2509                 isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
2510                 return;
2511         }
2512         memcpy(ntp->rd.data, aep, QENTRY_LEN);
2513         ntp->rd.nt.nt_hba = tptr->restart_queue;
2514         tptr->restart_queue = ntp;
2515         rls_lun_statep(isp, tptr);
2516 }
2517
2518 static void
2519 isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
2520 {
2521         int cdbxlen;
2522         uint16_t lun, chan, nphdl = NIL_HANDLE;
2523         uint32_t did, sid;
2524         uint64_t wwn = INI_NONE;
2525         fcportdb_t *lp;
2526         tstate_t *tptr;
2527         struct ccb_accept_tio *atiop;
2528         atio_private_data_t *atp = NULL;
2529         atio_private_data_t *oatp;
2530         inot_private_data_t *ntp;
2531
2532         did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2];
2533         sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
2534         lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | aep->at_cmnd.fcp_cmnd_lun[1];
2535
2536         /*
2537          * Find the N-port handle, and Virtual Port Index for this command.
2538          *
2539          * If we can't, we're somewhat in trouble because we can't actually respond w/o that information.
2540          * We also, as a matter of course, need to know the WWN of the initiator too.
2541          */
2542         if (ISP_CAP_MULTI_ID(isp)) {
2543                 /*
2544                  * Find the right channel based upon D_ID
2545                  */
2546                 isp_find_chan_by_did(isp, did, &chan);
2547
2548                 if (chan == ISP_NOCHAN) {
2549                         NANOTIME_T now;
2550
2551                         /*
2552                          * If we don't recognizer our own D_DID, terminate the exchange, unless we're within 2 seconds of startup
2553                          * It's a bit tricky here as we need to stash this command *somewhere*.
2554                          */
2555                         GET_NANOTIME(&now);
2556                         if (NANOTIME_SUB(&isp->isp_init_time, &now) > 2000000000ULL) {
2557                                 isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- dropping", __func__, aep->at_rxid, did);
2558                                 isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0);
2559                                 return;
2560                         }
2561                         tptr = get_lun_statep(isp, 0, 0);
2562                         if (tptr == NULL) {
2563                                 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
2564                                 if (tptr == NULL) {
2565                                         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);
2566                                         isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0);
2567                                         return;
2568                                 }
2569                         }
2570                         isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- deferring", __func__, aep->at_rxid, did);
2571                         goto noresrc;
2572                 }
2573                 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);
2574         } else {
2575                 chan = 0;
2576         }
2577
2578         /*
2579          * Find the PDB entry for this initiator
2580          */
2581         if (isp_find_pdb_by_sid(isp, chan, sid, &lp) == 0) {
2582                 /*
2583                  * If we're not in the port database terminate the exchange.
2584                  */
2585                 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",
2586                     __func__, aep->at_rxid, did, chan, sid);
2587                 isp_endcmd(isp, aep, NIL_HANDLE, chan, ECMD_TERMINATE, 0);
2588                 return;
2589         }
2590         nphdl = lp->handle;
2591         wwn = lp->port_wwn;
2592
2593         /*
2594          * Get the tstate pointer
2595          */
2596         tptr = get_lun_statep(isp, chan, lun);
2597         if (tptr == NULL) {
2598                 tptr = get_lun_statep(isp, chan, CAM_LUN_WILDCARD);
2599                 if (tptr == NULL) {
2600                         isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %d or wildcard", __func__, aep->at_rxid, lun);
2601                         if (lun == 0) {
2602                                 isp_endcmd(isp, aep, nphdl, SCSI_STATUS_BUSY, 0);
2603                         } else {
2604                                 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
2605                         }
2606                         return;
2607                 }
2608         }
2609
2610         /*
2611          * Start any commands pending resources first.
2612          */
2613         if (tptr->restart_queue) {
2614                 inot_private_data_t *restart_queue = tptr->restart_queue;
2615                 tptr->restart_queue = NULL;
2616                 while (restart_queue) {
2617                         ntp = restart_queue;
2618                         restart_queue = ntp->rd.nt.nt_hba;
2619                         isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid);
2620                         isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data);
2621                         isp_put_ntpd(isp, tptr, ntp);
2622                         /*
2623                          * If a recursion caused the restart queue to start to fill again,
2624                          * stop and splice the new list on top of the old list and restore
2625                          * it and go to noresrc.
2626                          */
2627                         if (tptr->restart_queue) {
2628                                 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restart queue refilling", __func__);
2629                                 if (restart_queue) {
2630                                         ntp = tptr->restart_queue;
2631                                         tptr->restart_queue = restart_queue;
2632                                         while (restart_queue->rd.nt.nt_hba) {
2633                                                 restart_queue = restart_queue->rd.nt.nt_hba;
2634                                         }
2635                                         restart_queue->rd.nt.nt_hba = ntp;
2636                                 }
2637                                 goto noresrc;
2638                         }
2639                 }
2640         }
2641
2642         /*
2643          * If the f/w is out of resources, just send a BUSY status back.
2644          */
2645         if (aep->at_rxid == AT7_NORESRC_RXID) {
2646                 rls_lun_statep(isp, tptr);
2647                 isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
2648                 return;
2649         }
2650
2651         /*
2652          * If we're out of resources, just send a BUSY status back.
2653          */
2654         atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
2655         if (atiop == NULL) {
2656                 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atios", aep->at_rxid);
2657                 goto noresrc;
2658         }
2659
2660         oatp = isp_find_atpd(isp, tptr, aep->at_rxid);
2661         if (oatp) {
2662                 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",
2663                     aep->at_rxid, nphdl, sid, aep->at_hdr.ox_id, oatp->state);
2664                 /*
2665                  * It's not a "no resource" condition- but we can treat it like one
2666                  */
2667                 goto noresrc;
2668         }
2669         atp = isp_get_atpd(isp, tptr, aep->at_rxid);
2670         if (atp == NULL) {
2671                 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atps", aep->at_rxid);
2672                 goto noresrc;
2673         }
2674         atp->word3 = lp->prli_word3;
2675         atp->state = ATPD_STATE_ATIO;
2676         SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
2677         tptr->atio_count--;
2678         ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO count now %d\n", tptr->atio_count);
2679         atiop->init_id = nphdl;
2680         atiop->ccb_h.target_id = FCPARAM(isp, chan)->isp_loopid;
2681         atiop->ccb_h.target_lun = lun;
2682         atiop->sense_len = 0;
2683         cdbxlen = aep->at_cmnd.fcp_cmnd_alen_datadir >> FCP_CMND_ADDTL_CDBLEN_SHIFT;
2684         if (cdbxlen) {
2685                 isp_prt(isp, ISP_LOGWARN, "additional CDBLEN ignored");
2686         }
2687         cdbxlen = sizeof (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb);
2688         ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb, cdbxlen);
2689         atiop->cdb_len = cdbxlen;
2690         atiop->ccb_h.status = CAM_CDB_RECVD;
2691         atiop->tag_id = atp->tag;
2692         switch (aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK) {
2693         case FCP_CMND_TASK_ATTR_SIMPLE:
2694                 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
2695                 atiop->tag_action = MSG_SIMPLE_Q_TAG;
2696                 break;
2697         case FCP_CMND_TASK_ATTR_HEAD:
2698                 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
2699                 atiop->tag_action = MSG_HEAD_OF_Q_TAG;
2700                 break;
2701         case FCP_CMND_TASK_ATTR_ORDERED:
2702                 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
2703                 atiop->tag_action = MSG_ORDERED_Q_TAG;
2704                 break;
2705         default:
2706                 /* FALLTHROUGH */
2707         case FCP_CMND_TASK_ATTR_ACA:
2708         case FCP_CMND_TASK_ATTR_UNTAGGED:
2709                 atiop->tag_action = 0;
2710                 break;
2711         }
2712         atp->orig_datalen = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
2713         atp->bytes_xfered = 0;
2714         atp->lun = lun;
2715         atp->nphdl = nphdl;
2716         atp->portid = sid;
2717         atp->oxid = aep->at_hdr.ox_id;
2718         atp->rxid = aep->at_hdr.rx_id;
2719         atp->cdb0 = atiop->cdb_io.cdb_bytes[0];
2720         atp->tattr = aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK;
2721         atp->state = ATPD_STATE_CAM;
2722         isp_prt(isp, ISP_LOGTDEBUG0, "ATIO7[0x%x] CDB=0x%x lun %d datalen %u", aep->at_rxid, atp->cdb0, lun, atp->orig_datalen);
2723         xpt_done((union ccb *)atiop);
2724         rls_lun_statep(isp, tptr);
2725         return;
2726 noresrc:
2727         if (atp) {
2728                 isp_put_atpd(isp, tptr, atp);
2729         }
2730         ntp = isp_get_ntpd(isp, tptr);
2731         if (ntp == NULL) {
2732                 rls_lun_statep(isp, tptr);
2733                 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
2734                 return;
2735         }
2736         memcpy(ntp->rd.data, aep, QENTRY_LEN);
2737         ntp->rd.nt.nt_hba = tptr->restart_queue;
2738         tptr->restart_queue = ntp;
2739         rls_lun_statep(isp, tptr);
2740 }
2741
2742
2743 /*
2744  * Handle starting an SRR (sequence retransmit request)
2745  * We get here when we've gotten the immediate notify
2746  * and the return of all outstanding CTIOs for this
2747  * transaction.
2748  */
2749 static void
2750 isp_handle_srr_start(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp)
2751 {
2752         in_fcentry_24xx_t *inot;
2753         uint32_t srr_off, ccb_off, ccb_len, ccb_end;
2754         union ccb *ccb;
2755
2756         inot = (in_fcentry_24xx_t *)atp->srr;
2757         srr_off = inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16);
2758         ccb = atp->srr_ccb;
2759         atp->srr_ccb = NULL;
2760         atp->nsrr++;
2761         if (ccb == NULL) {
2762                 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] null ccb", atp->tag);
2763                 goto fail;
2764         }
2765
2766         ccb_off = ccb->ccb_h.spriv_field0;
2767         ccb_len = ccb->csio.dxfer_len;
2768         ccb_end = (ccb_off == ~0)? ~0 : ccb_off + ccb_len;
2769
2770         switch (inot->in_srr_iu) {
2771         case R_CTL_INFO_SOLICITED_DATA:
2772                 /*
2773                  * We have to restart a FCP_DATA data out transaction
2774                  */
2775                 atp->sendst = 0;
2776                 atp->bytes_xfered = srr_off;
2777                 if (ccb_len == 0) {
2778                         isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x but current CCB doesn't transfer data", atp->tag, srr_off);
2779                         goto mdp;
2780                 }
2781                 if (srr_off < ccb_off || ccb_off > srr_off + ccb_len) {
2782                         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);
2783                         goto mdp;
2784                 }
2785                 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);
2786                 break;
2787         case R_CTL_INFO_COMMAND_STATUS:
2788                 isp_prt(isp, ISP_LOGTINFO, "SRR[0x%x] Got an FCP RSP SRR- resending status", atp->tag);
2789                 atp->sendst = 1;
2790                 /*
2791                  * We have to restart a FCP_RSP IU transaction
2792                  */
2793                 break;
2794         case R_CTL_INFO_DATA_DESCRIPTOR:
2795                 /*
2796                  * We have to restart an FCP DATA in transaction
2797                  */
2798                 isp_prt(isp, ISP_LOGWARN, "Got an FCP DATA IN SRR- dropping");
2799                 goto fail;
2800                 
2801         default:
2802                 isp_prt(isp, ISP_LOGWARN, "Got an unknown information (%x) SRR- dropping", inot->in_srr_iu);
2803                 goto fail;
2804         }
2805
2806         /*
2807          * We can't do anything until this is acked, so we might as well start it now.
2808          * We aren't going to do the usual asynchronous ack issue because we need
2809          * to make sure this gets on the wire first.
2810          */
2811         if (isp_notify_ack(isp, inot)) {
2812                 isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose");
2813                 goto fail;
2814         }
2815         isp_target_start_ctio(isp, ccb, FROM_SRR);
2816         return;
2817 fail:
2818         inot->in_reserved = 1;
2819         isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
2820         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2821         ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
2822         isp_complete_ctio(ccb);
2823         return;
2824 mdp:
2825         if (isp_notify_ack(isp, inot)) {
2826                 isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose");
2827                 goto fail;
2828         }
2829         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2830         ccb->ccb_h.status = CAM_MESSAGE_RECV;
2831         /*
2832          * This is not a strict interpretation of MDP, but it's close
2833          */
2834         ccb->csio.msg_ptr = &ccb->csio.sense_data.sense_buf[SSD_FULL_SIZE - 16];
2835         ccb->csio.msg_len = 7;
2836         ccb->csio.msg_ptr[0] = MSG_EXTENDED;
2837         ccb->csio.msg_ptr[1] = 5;
2838         ccb->csio.msg_ptr[2] = 0;       /* modify data pointer */
2839         ccb->csio.msg_ptr[3] = srr_off >> 24;
2840         ccb->csio.msg_ptr[4] = srr_off >> 16;
2841         ccb->csio.msg_ptr[5] = srr_off >> 8;
2842         ccb->csio.msg_ptr[6] = srr_off;
2843         isp_complete_ctio(ccb);
2844 }
2845
2846
2847 static void
2848 isp_handle_srr_notify(ispsoftc_t *isp, void *inot_raw)
2849 {
2850         tstate_t *tptr;
2851         in_fcentry_24xx_t *inot = inot_raw;
2852         atio_private_data_t *atp;
2853         uint32_t tag = inot->in_rxid;
2854         uint32_t bus = inot->in_vpidx;
2855
2856         if (!IS_24XX(isp)) {
2857                 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_raw);
2858                 return;
2859         }
2860
2861         tptr = get_lun_statep_from_tag(isp, bus, tag);
2862         if (tptr == NULL) {
2863                 isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x in SRR Notify", __func__, tag);
2864                 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
2865                 return;
2866         }
2867         atp = isp_find_atpd(isp, tptr, tag);
2868         if (atp == NULL) {
2869                 rls_lun_statep(isp, tptr);
2870                 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify", __func__, tag);
2871                 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
2872                 return;
2873         }
2874         atp->srr_notify_rcvd = 1;
2875         memcpy(atp->srr, inot, sizeof (atp->srr));
2876         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,
2877             inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16));
2878         if (atp->srr_ccb)
2879                 isp_handle_srr_start(isp, tptr, atp);
2880         rls_lun_statep(isp, tptr);
2881 }
2882
2883 static void
2884 isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
2885 {
2886         union ccb *ccb;
2887         int sentstatus = 0, ok = 0, notify_cam = 0, resid = 0, failure = 0;
2888         tstate_t *tptr = NULL;
2889         atio_private_data_t *atp = NULL;
2890         int bus;
2891         uint32_t handle, moved_data = 0, data_requested;
2892
2893         /*
2894          * CTIO handles are 16 bits.
2895          * CTIO2 and CTIO7 are 32 bits.
2896          */
2897
2898         if (IS_SCSI(isp)) {
2899                 handle = ((ct_entry_t *)arg)->ct_syshandle;
2900         } else {
2901                 handle = ((ct2_entry_t *)arg)->ct_syshandle;
2902         }
2903         ccb = isp_find_xs_tgt(isp, handle);
2904         if (ccb == NULL) {
2905                 isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg);
2906                 return;
2907         }
2908         isp_destroy_tgt_handle(isp, handle);
2909         data_requested = PISP_PCMD(ccb)->datalen;
2910         isp_free_pcmd(isp, ccb);
2911         if (isp->isp_nactive) {
2912                 isp->isp_nactive--;
2913         }
2914
2915         bus = XS_CHANNEL(ccb);
2916         tptr = get_lun_statep(isp, bus, XS_LUN(ccb));
2917         if (tptr == NULL) {
2918                 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
2919         }
2920         if (tptr == NULL) {
2921                 isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x after I/O", __func__, ccb->csio.tag_id);
2922                 return;
2923         }
2924
2925         if (IS_24XX(isp)) {
2926                 atp = isp_find_atpd(isp, tptr, ((ct7_entry_t *)arg)->ct_rxid);
2927         } else if (IS_FC(isp)) {
2928                 atp = isp_find_atpd(isp, tptr, ((ct2_entry_t *)arg)->ct_rxid);
2929         } else {
2930                 atp = isp_find_atpd(isp, tptr, ((ct_entry_t *)arg)->ct_fwhandle);
2931         }
2932         if (atp == NULL) {
2933                 rls_lun_statep(isp, tptr);
2934                 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ccb->csio.tag_id);
2935                 return;
2936         }
2937         KASSERT((atp->ctcnt > 0), ("ctio count not greater than zero"));
2938         atp->bytes_in_transit -= data_requested;
2939         atp->ctcnt -= 1;
2940         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2941
2942         if (IS_24XX(isp)) {
2943                 ct7_entry_t *ct = arg;
2944
2945                 if (ct->ct_nphdl == CT7_SRR) {
2946                         atp->srr_ccb = ccb;
2947                         if (atp->srr_notify_rcvd)
2948                                 isp_handle_srr_start(isp, tptr, atp);
2949                         rls_lun_statep(isp, tptr);
2950                         return;
2951                 }
2952                 if (ct->ct_nphdl == CT_HBA_RESET) {
2953                         failure = CAM_UNREC_HBA_ERROR;
2954                 } else {
2955                         sentstatus = ct->ct_flags & CT7_SENDSTATUS;
2956                         ok = (ct->ct_nphdl == CT7_OK);
2957                         notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0;
2958                         if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) {
2959                                 resid = ct->ct_resid;
2960                                 moved_data = data_requested - resid;
2961                         }
2962                 }
2963                 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),
2964                    notify_cam, ct->ct_nphdl, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
2965         } else if (IS_FC(isp)) {
2966                 ct2_entry_t *ct = arg;
2967                 if (ct->ct_status == CT_SRR) {
2968                         atp->srr_ccb = ccb;
2969                         if (atp->srr_notify_rcvd)
2970                                 isp_handle_srr_start(isp, tptr, atp);
2971                         rls_lun_statep(isp, tptr);
2972                         isp_target_putback_atio(ccb);
2973                         return;
2974                 }
2975                 if (ct->ct_status == CT_HBA_RESET) {
2976                         failure = CAM_UNREC_HBA_ERROR;
2977                 } else {
2978                         sentstatus = ct->ct_flags & CT2_SENDSTATUS;
2979                         ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
2980                         notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0;
2981                         if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
2982                                 resid = ct->ct_resid;
2983                                 moved_data = data_requested - resid;
2984                         }
2985                 }
2986                 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),
2987                     notify_cam, ct->ct_status, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
2988         } else {
2989                 ct_entry_t *ct = arg;
2990
2991                 if (ct->ct_status == (CT_HBA_RESET & 0xff)) {
2992                         failure = CAM_UNREC_HBA_ERROR;
2993                 } else {
2994                         sentstatus = ct->ct_flags & CT_SENDSTATUS;
2995                         ok = (ct->ct_status  & ~QLTM_SVALID) == CT_OK;
2996                         notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0;
2997                 }
2998                 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
2999                         resid = ct->ct_resid;
3000                         moved_data = data_requested - resid;
3001                 }
3002                 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO[%x] seq %u nc %d tag %x S_ID 0x%x lun %d sts %x flg %x resid %d %s", __func__, ct->ct_fwhandle, ATPD_GET_SEQNO(ct),
3003                     notify_cam, ct->ct_tag_val, ct->ct_iid, ct->ct_lun, ct->ct_status, ct->ct_flags, resid, sentstatus? "FIN" : "MID");
3004         }
3005         if (ok) {
3006                 if (moved_data) {
3007                         atp->bytes_xfered += moved_data;
3008                         ccb->csio.resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit;
3009                 }
3010                 if (sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) {
3011                         ccb->ccb_h.status |= CAM_SENT_SENSE;
3012                 }
3013                 ccb->ccb_h.status |= CAM_REQ_CMP;
3014         } else {
3015                 notify_cam = 1;
3016                 if (failure == CAM_UNREC_HBA_ERROR)
3017                         ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR;
3018                 else
3019                         ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
3020         }
3021         atp->state = ATPD_STATE_PDON;
3022         rls_lun_statep(isp, tptr);
3023
3024         /*
3025          * We never *not* notify CAM when there has been any error (ok == 0),
3026          * so we never need to do an ATIO putback if we're not notifying CAM.
3027          */
3028         isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done (ok=%d nc=%d nowsendstatus=%d ccb ss=%d)",
3029             (sentstatus)? "  FINAL " : "MIDTERM ", atp->tag, ok, notify_cam, atp->sendst, (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0);
3030         if (notify_cam == 0) {
3031                 if (atp->sendst) {
3032                         isp_target_start_ctio(isp, ccb, FROM_CTIO_DONE);
3033                 }
3034                 return;
3035         }
3036
3037         /*
3038          * We're telling CAM we're done with this CTIO transaction.
3039          *
3040          * 24XX cards never need an ATIO put back.
3041          *
3042          * Other cards need one put back only on error.
3043          * In the latter case, a timeout will re-fire
3044          * and try again in case we didn't have
3045          * queue resources to do so at first. In any case,
3046          * once the putback is done we do the completion
3047          * call.
3048          */
3049         if (ok || IS_24XX(isp)) {
3050                 isp_complete_ctio(ccb);
3051         } else {
3052                 isp_target_putback_atio(ccb);
3053         }
3054 }
3055
3056 static void
3057 isp_handle_platform_notify_scsi(ispsoftc_t *isp, in_entry_t *inot)
3058 {
3059         isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
3060 }
3061
3062 static void
3063 isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
3064 {
3065         int needack = 1;
3066         switch (inp->in_status) {
3067         case IN_PORT_LOGOUT:
3068                 /*
3069                  * XXX: Need to delete this initiator's WWN from the database
3070                  * XXX: Need to send this LOGOUT upstream
3071                  */
3072                 isp_prt(isp, ISP_LOGWARN, "port logout of S_ID 0x%x", inp->in_iid);
3073                 break;
3074         case IN_PORT_CHANGED:
3075                 isp_prt(isp, ISP_LOGWARN, "port changed for S_ID 0x%x", inp->in_iid);
3076                 break;
3077         case IN_GLOBAL_LOGO:
3078                 isp_del_all_wwn_entries(isp, 0);
3079                 isp_prt(isp, ISP_LOGINFO, "all ports logged out");
3080                 break;
3081         case IN_ABORT_TASK:
3082         {
3083                 tstate_t *tptr;
3084                 uint16_t lun;
3085                 uint32_t loopid;
3086                 uint64_t wwn;
3087                 atio_private_data_t *atp;
3088                 fcportdb_t *lp;
3089                 struct ccb_immediate_notify *inot = NULL;
3090
3091                 if (ISP_CAP_SCCFW(isp)) {
3092                         lun = inp->in_scclun;
3093                 } else {
3094                         lun = inp->in_lun;
3095                 }
3096                 if (ISP_CAP_2KLOGIN(isp)) {
3097                         loopid = ((in_fcentry_e_t *)inp)->in_iid;
3098                 } else {
3099                         loopid = inp->in_iid;
3100                 }
3101                 if (isp_find_pdb_by_loopid(isp, 0, loopid, &lp)) {
3102                         wwn = lp->port_wwn;
3103                 } else {
3104                         wwn = INI_ANY;
3105                 }
3106                 tptr = get_lun_statep(isp, 0, lun);
3107                 if (tptr == NULL) {
3108                         tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
3109                         if (tptr == NULL) {
3110                                 isp_prt(isp, ISP_LOGWARN, "ABORT TASK for lun %u- but no tstate", lun);
3111                                 return;
3112                         }
3113                 }
3114                 atp = isp_find_atpd(isp, tptr, inp->in_seqid);
3115
3116                 if (atp) {
3117                         inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots);
3118                         isp_prt(isp, ISP_LOGTDEBUG0, "ABORT TASK RX_ID %x WWN 0x%016llx state %d", inp->in_seqid, (unsigned long long) wwn, atp->state);
3119                         if (inot) {
3120                                 tptr->inot_count--;
3121                                 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
3122                                 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count);
3123                         } else {
3124                                 ISP_PATH_PRT(isp, ISP_LOGWARN, tptr->owner, "out of INOT structures\n");
3125                         }
3126                 } else {
3127                         ISP_PATH_PRT(isp, ISP_LOGWARN, tptr->owner, "abort task RX_ID %x from wwn 0x%016llx, state unknown\n", inp->in_seqid, wwn);
3128                 }
3129                 if (inot) {
3130                         isp_notify_t tmp, *nt = &tmp;
3131                         ISP_MEMZERO(nt, sizeof (isp_notify_t));
3132                         nt->nt_hba = isp;
3133                         nt->nt_tgt = FCPARAM(isp, 0)->isp_wwpn;
3134                         nt->nt_wwn = wwn;
3135                         nt->nt_nphdl = loopid;
3136                         nt->nt_sid = PORT_ANY;
3137                         nt->nt_did = PORT_ANY;
3138                         nt->nt_lun = lun;
3139                         nt->nt_need_ack = 1;
3140                         nt->nt_channel = 0;
3141                         nt->nt_ncode = NT_ABORT_TASK;
3142                         nt->nt_lreserved = inot;
3143                         isp_handle_platform_target_tmf(isp, nt);
3144                         needack = 0;
3145                 }
3146                 rls_lun_statep(isp, tptr);
3147                 break;
3148         }
3149         default:
3150                 break;
3151         }
3152         if (needack) {
3153                 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp);
3154         }
3155 }
3156
3157 static void
3158 isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot)
3159 {
3160         uint16_t nphdl;
3161         uint16_t prli_options = 0;
3162         uint32_t portid;
3163         fcportdb_t *lp;
3164         uint8_t *ptr = NULL;
3165         uint64_t wwn;
3166
3167         nphdl = inot->in_nphdl;
3168         if (nphdl != NIL_HANDLE) {
3169                 portid = inot->in_portid_hi << 16 | inot->in_portid_lo;
3170         } else {
3171                 portid = PORT_ANY;
3172         }
3173
3174         switch (inot->in_status) {
3175         case IN24XX_ELS_RCVD:
3176         {
3177                 char buf[16], *msg;
3178                 int chan = ISP_GET_VPIDX(isp, inot->in_vpidx);
3179
3180                 /*
3181                  * Note that we're just getting notification that an ELS was received
3182                  * (possibly with some associated information sent upstream). This is
3183                  * *not* the same as being given the ELS frame to accept or reject.
3184                  */
3185                 switch (inot->in_status_subcode) {
3186                 case LOGO:
3187                         msg = "LOGO";
3188                         if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) {
3189                                 ptr = (uint8_t *)inot;  /* point to unswizzled entry! */
3190                                 wwn =   (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF])   << 56) |
3191                                         (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+1]) << 48) |
3192                                         (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+2]) << 40) |
3193                                         (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+3]) << 32) |
3194                                         (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+4]) << 24) |
3195                                         (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+5]) << 16) |
3196                                         (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+6]) <<  8) |
3197                                         (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+7]));
3198                         } else {
3199                                 wwn = INI_ANY;
3200                         }
3201                         isp_del_wwn_entry(isp, chan, wwn, nphdl, portid);
3202                         break;
3203                 case PRLO:
3204                         msg = "PRLO";
3205                         break;
3206                 case PLOGI:
3207                 case PRLI:
3208                         /*
3209                          * Treat PRLI the same as PLOGI and make a database entry for it.
3210                          */
3211                         if (inot->in_status_subcode == PLOGI) {
3212                                 msg = "PLOGI";
3213                         } else {
3214                                 prli_options = inot->in_prli_options;
3215                                 msg = "PRLI";
3216                         }
3217                         if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) {
3218                                 ptr = (uint8_t *)inot;  /* point to unswizzled entry! */
3219                                 wwn =   (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF])   << 56) |
3220                                         (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+1]) << 48) |
3221                                         (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+2]) << 40) |
3222                                         (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+3]) << 32) |
3223                                         (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+4]) << 24) |
3224                                         (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+5]) << 16) |
3225                                         (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+6]) <<  8) |
3226                                         (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+7]));
3227                         } else {
3228                                 wwn = INI_NONE;
3229                         }
3230                         isp_add_wwn_entry(isp, chan, wwn, nphdl, portid, prli_options);
3231                         break;
3232                 case PDISC:
3233                         msg = "PDISC";
3234                         break;
3235                 case ADISC:
3236                         msg = "ADISC";
3237                         break;
3238                 default:
3239                         ISP_SNPRINTF(buf, sizeof (buf), "ELS 0x%x", inot->in_status_subcode);
3240                         msg = buf;
3241                         break;
3242                 }
3243                 if (inot->in_flags & IN24XX_FLAG_PUREX_IOCB) {
3244                         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);
3245                         break;
3246                 }
3247                 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,
3248                     inot->in_rxid, inot->in_oxid);
3249                 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
3250                 break;
3251         }
3252
3253         case IN24XX_PORT_LOGOUT:
3254                 ptr = "PORT LOGOUT";
3255                 if (isp_find_pdb_by_loopid(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, &lp)) {
3256                         isp_del_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), lp->port_wwn, nphdl, lp->portid);
3257                 }
3258                 /* FALLTHROUGH */
3259         case IN24XX_PORT_CHANGED:
3260                 if (ptr == NULL) {
3261                         ptr = "PORT CHANGED";
3262                 }
3263                 /* FALLTHROUGH */
3264         case IN24XX_LIP_RESET: 
3265                 if (ptr == NULL) {
3266                         ptr = "LIP RESET";
3267                 }
3268                 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), ptr, inot->in_status_subcode, nphdl);
3269
3270                 /*
3271                  * All subcodes here are irrelevant. What is relevant
3272                  * is that we need to terminate all active commands from
3273                  * this initiator (known by N-port handle).
3274                  */
3275                 /* XXX IMPLEMENT XXX */
3276                 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
3277                 break;
3278
3279         case IN24XX_SRR_RCVD:
3280 #ifdef  ISP_TARGET_MODE
3281                 isp_handle_srr_notify(isp, inot);
3282                 break;
3283 #else
3284                 if (ptr == NULL) {
3285                         ptr = "SRR RCVD";
3286                 }
3287                 /* FALLTHROUGH */
3288 #endif
3289         case IN24XX_LINK_RESET:
3290                 if (ptr == NULL) {
3291                         ptr = "LINK RESET";
3292                 }
3293         case IN24XX_LINK_FAILED:
3294                 if (ptr == NULL) {
3295                         ptr = "LINK FAILED";
3296                 }
3297         default:
3298                 isp_prt(isp, ISP_LOGWARN, "Chan %d %s", ISP_GET_VPIDX(isp, inot->in_vpidx), ptr);
3299                 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
3300                 break;
3301         }
3302 }
3303
3304 static int
3305 isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp)
3306 {
3307
3308         if (isp->isp_state != ISP_RUNSTATE) {
3309                 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", mp->nt_ncode, mp->nt_lreserved != NULL);
3310                 return (0);
3311         }
3312
3313         /*
3314          * This case is for a Task Management Function, which shows up as an ATIO7 entry.
3315          */
3316         if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ATIO) {
3317                 ct7_entry_t local, *cto = &local;
3318                 at7_entry_t *aep = (at7_entry_t *)mp->nt_lreserved;
3319                 fcportdb_t *lp;
3320                 uint32_t sid;
3321                 uint16_t nphdl;
3322
3323                 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
3324                 if (isp_find_pdb_by_sid(isp, mp->nt_channel, sid, &lp)) {
3325                         nphdl = lp->handle;
3326                 } else {
3327                         nphdl = NIL_HANDLE;
3328                 }
3329                 ISP_MEMZERO(&local, sizeof (local));
3330                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
3331                 cto->ct_header.rqs_entry_count = 1;
3332                 cto->ct_nphdl = nphdl;
3333                 cto->ct_rxid = aep->at_rxid;
3334                 cto->ct_vpidx = mp->nt_channel;
3335                 cto->ct_iid_lo = sid;
3336                 cto->ct_iid_hi = sid >> 16;
3337                 cto->ct_oxid = aep->at_hdr.ox_id;
3338                 cto->ct_flags = CT7_SENDSTATUS|CT7_NOACK|CT7_NO_DATA|CT7_FLAG_MODE1;
3339                 cto->ct_flags |= (aep->at_ta_len >> 12) << CT7_TASK_ATTR_SHIFT;
3340                 return (isp_target_put_entry(isp, &local));
3341         }
3342
3343         /*
3344          * This case is for a responding to an ABTS frame
3345          */
3346         if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
3347
3348                 /*
3349                  * Overload nt_need_ack here to mark whether we've terminated the associated command.
3350                  */
3351                 if (mp->nt_need_ack) {
3352                         uint8_t storage[QENTRY_LEN];
3353                         ct7_entry_t *cto = (ct7_entry_t *) storage;
3354                         abts_t *abts = (abts_t *)mp->nt_lreserved;
3355
3356                         ISP_MEMZERO(cto, sizeof (ct7_entry_t));
3357                         isp_prt(isp, ISP_LOGTDEBUG0, "%s: [%x] terminating after ABTS received", __func__, abts->abts_rxid_task);
3358                         cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
3359                         cto->ct_header.rqs_entry_count = 1;
3360                         cto->ct_nphdl = mp->nt_nphdl;
3361                         cto->ct_rxid = abts->abts_rxid_task;
3362                         cto->ct_iid_lo = mp->nt_sid;
3363                         cto->ct_iid_hi = mp->nt_sid >> 16;
3364                         cto->ct_oxid = abts->abts_ox_id;
3365                         cto->ct_vpidx = mp->nt_channel;
3366                         cto->ct_flags = CT7_NOACK|CT7_TERMINATE;
3367                         if (isp_target_put_entry(isp, cto)) {
3368                                 return (ENOMEM);
3369                         }
3370                         mp->nt_need_ack = 0;
3371                 }
3372                 if (isp_acknak_abts(isp, mp->nt_lreserved, 0) == ENOMEM) {
3373                         return (ENOMEM);
3374                 } else {
3375                         return (0);
3376                 }
3377         }
3378
3379         /*
3380          * Handle logout cases here
3381          */
3382         if (mp->nt_ncode == NT_GLOBAL_LOGOUT) {
3383                 isp_del_all_wwn_entries(isp, mp->nt_channel);
3384         }
3385
3386         if (mp->nt_ncode == NT_LOGOUT) {
3387                 if (!IS_2100(isp) && IS_FC(isp)) {
3388                         isp_del_wwn_entries(isp, mp);
3389                 }
3390         }
3391
3392         /*
3393          * General purpose acknowledgement
3394          */
3395         if (mp->nt_need_ack) {
3396                 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) being acked", mp->nt_ncode, mp->nt_lreserved != NULL);
3397                 /*
3398                  * Don't need to use the guaranteed send because the caller can retry
3399                  */
3400                 return (isp_notify_ack(isp, mp->nt_lreserved));
3401         }
3402         return (0);
3403 }
3404
3405 /*
3406  * Handle task management functions.
3407  *
3408  * We show up here with a notify structure filled out.
3409  *
3410  * The nt_lreserved tag points to the original queue entry
3411  */
3412 static void
3413 isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify)
3414 {
3415         tstate_t *tptr;
3416         fcportdb_t *lp;
3417         struct ccb_immediate_notify *inot;
3418         inot_private_data_t *ntp = NULL;
3419         lun_id_t lun;
3420
3421         isp_prt(isp, ISP_LOGTDEBUG0, "%s: code 0x%x sid  0x%x tagval 0x%016llx chan %d lun 0x%x", __func__, notify->nt_ncode,
3422             notify->nt_sid, (unsigned long long) notify->nt_tagval, notify->nt_channel, notify->nt_lun);
3423         /*
3424          * NB: This assignment is necessary because of tricky type conversion.
3425          * XXX: This is tricky and I need to check this. If the lun isn't known
3426          * XXX: for the task management function, it does not of necessity follow
3427          * XXX: that it should go up stream to the wildcard listener.
3428          */
3429         if (notify->nt_lun == LUN_ANY) {
3430                 lun = CAM_LUN_WILDCARD;
3431         } else {
3432                 lun = notify->nt_lun;
3433         }
3434         tptr = get_lun_statep(isp, notify->nt_channel, lun);
3435         if (tptr == NULL) {
3436                 tptr = get_lun_statep(isp, notify->nt_channel, CAM_LUN_WILDCARD);
3437                 if (tptr == NULL) {
3438                         isp_prt(isp, ISP_LOGWARN, "%s: no state pointer found for chan %d lun %#jx", __func__, notify->nt_channel, (uintmax_t)lun);
3439                         goto bad;
3440                 }
3441         }
3442         inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots);
3443         if (inot == NULL) {
3444                 isp_prt(isp, ISP_LOGWARN, "%s: out of immediate notify structures for chan %d lun %#jx", __func__, notify->nt_channel, (uintmax_t)lun);
3445                 goto bad;
3446         }
3447
3448         if (isp_find_pdb_by_sid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0) {
3449                 inot->initiator_id = CAM_TARGET_WILDCARD;
3450         } else {
3451                 inot->initiator_id = lp->handle;
3452         }
3453         inot->seq_id = notify->nt_tagval;
3454         inot->tag_id = notify->nt_tagval >> 32;
3455
3456         switch (notify->nt_ncode) {
3457         case NT_ABORT_TASK:
3458                 isp_target_mark_aborted_early(isp, tptr, inot->tag_id);
3459                 inot->arg = MSG_ABORT_TASK;
3460                 break;
3461         case NT_ABORT_TASK_SET:
3462                 isp_target_mark_aborted_early(isp, tptr, TAG_ANY);
3463                 inot->arg = MSG_ABORT_TASK_SET;
3464                 break;
3465         case NT_CLEAR_ACA:
3466                 inot->arg = MSG_CLEAR_ACA;
3467                 break;
3468         case NT_CLEAR_TASK_SET:
3469                 inot->arg = MSG_CLEAR_TASK_SET;
3470                 break;
3471         case NT_LUN_RESET:
3472                 inot->arg = MSG_LOGICAL_UNIT_RESET;
3473                 break;
3474         case NT_TARGET_RESET:
3475                 inot->arg = MSG_TARGET_RESET;
3476                 break;
3477         default:
3478                 isp_prt(isp, ISP_LOGWARN, "%s: unknown TMF code 0x%x for chan %d lun %#jx", __func__, notify->nt_ncode, notify->nt_channel, (uintmax_t)lun);
3479                 goto bad;
3480         }
3481
3482         ntp = isp_get_ntpd(isp, tptr);
3483         if (ntp == NULL) {
3484                 isp_prt(isp, ISP_LOGWARN, "%s: out of inotify private structures", __func__);
3485                 goto bad;
3486         }
3487         ISP_MEMCPY(&ntp->rd.nt, notify, sizeof (isp_notify_t));
3488         if (notify->nt_lreserved) {
3489                 ISP_MEMCPY(&ntp->rd.data, notify->nt_lreserved, QENTRY_LEN);
3490                 ntp->rd.nt.nt_lreserved = &ntp->rd.data;
3491         }
3492         ntp->rd.seq_id = notify->nt_tagval;
3493         ntp->rd.tag_id = notify->nt_tagval >> 32;
3494
3495         tptr->inot_count--;
3496         SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
3497         rls_lun_statep(isp, tptr);
3498         ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count);
3499         inot->ccb_h.status = CAM_MESSAGE_RECV;
3500         xpt_done((union ccb *)inot);
3501         return;
3502 bad:
3503         if (tptr) {
3504                 rls_lun_statep(isp, tptr);
3505         }
3506         if (notify->nt_need_ack && notify->nt_lreserved) {
3507                 if (((isphdr_t *)notify->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
3508                         if (isp_acknak_abts(isp, notify->nt_lreserved, ENOMEM)) {
3509                                 isp_prt(isp, ISP_LOGWARN, "you lose- unable to send an ACKNAK");
3510                         }
3511                 } else {
3512                         isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, notify->nt_lreserved);
3513                 }
3514         }
3515 }
3516
3517 /*
3518  * Find the associated private data and mark it as dead so
3519  * we don't try to work on it any further.
3520  */
3521 static void
3522 isp_target_mark_aborted(ispsoftc_t *isp, union ccb *ccb)
3523 {
3524         tstate_t *tptr;
3525         atio_private_data_t *atp;
3526         union ccb *accb = ccb->cab.abort_ccb;
3527
3528         tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
3529         if (tptr == NULL) {
3530                 tptr = get_lun_statep(isp, XS_CHANNEL(accb), CAM_LUN_WILDCARD);
3531                 if (tptr == NULL) {
3532                         ccb->ccb_h.status = CAM_REQ_INVALID;
3533                         return;
3534                 }
3535         }
3536
3537         atp = isp_find_atpd(isp, tptr, accb->atio.tag_id);
3538         if (atp == NULL) {
3539                 ccb->ccb_h.status = CAM_REQ_INVALID;
3540         } else {
3541                 atp->dead = 1;
3542                 ccb->ccb_h.status = CAM_REQ_CMP;
3543         }
3544         rls_lun_statep(isp, tptr);
3545 }
3546
3547 static void
3548 isp_target_mark_aborted_early(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id)
3549 {
3550         atio_private_data_t *atp;
3551         inot_private_data_t *restart_queue = tptr->restart_queue;
3552
3553         /*
3554          * First, clean any commands pending restart
3555          */
3556         tptr->restart_queue = NULL;
3557         while (restart_queue) {
3558                 uint32_t this_tag_id;
3559                 inot_private_data_t *ntp = restart_queue;
3560
3561                 restart_queue = ntp->rd.nt.nt_hba;
3562
3563                 if (IS_24XX(isp)) {
3564                         this_tag_id = ((at7_entry_t *)ntp->rd.data)->at_rxid;
3565                 } else {
3566                         this_tag_id = ((at2_entry_t *)ntp->rd.data)->at_rxid;
3567                 }
3568                 if ((uint64_t)tag_id == TAG_ANY || tag_id == this_tag_id) {
3569                         isp_put_ntpd(isp, tptr, ntp);
3570                 } else {
3571                         ntp->rd.nt.nt_hba = tptr->restart_queue;
3572                         tptr->restart_queue = ntp;
3573                 }
3574         }
3575
3576         /*
3577          * Now mark other ones dead as well.
3578          */
3579         for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
3580                 if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id) {
3581                         atp->dead = 1;
3582                 }
3583         }
3584 }
3585
3586
3587 #ifdef  ISP_INTERNAL_TARGET
3588 //#define       ISP_SEPARATE_STATUS     1
3589 #define ISP_MULTI_CCBS          1
3590 #if defined(ISP_MULTI_CCBS) && !defined(ISP_SEPARATE_STATUS)
3591 #define ISP_SEPARATE_STATUS 1
3592 #endif
3593
3594 typedef struct periph_private_data_t {
3595         union ccb *ccb;                 /* original ATIO or Immediate Notify */
3596         unsigned long   offset;         /* current offset */
3597         int             sequence;       /* current CTIO sequence */
3598         int             ctio_cnt;       /* current # of ctio's outstanding */
3599         int
3600                 status_sent     : 1,
3601                 on_queue        : 1;    /* on restart queue */
3602 } ppd_t;
3603 /*
3604  * Each ATIO we allocate will have periph private data associated with it
3605  * that maintains per-command state. This private to each ATIO.
3606  */
3607 #define ATIO_PPD(ccb)           ((ppd_t *)(((struct ccb_hdr *)ccb)->ppriv_ptr0))
3608 /*
3609  * Each CTIO we send downstream will get a pointer to the ATIO itself
3610  * so that on completion we can retrieve that pointer.
3611  */
3612 #define ccb_atio                ppriv_ptr1
3613 #define ccb_inot                ppriv_ptr1
3614
3615 /*
3616  * Each CTIO we send downstream will contain a sequence number
3617  */
3618 #define CTIO_SEQ(ccb)           ccb->ccb_h.ppriv_field0
3619
3620 #define MAX_ISP_TARG_TRANSFER   (2 << 20)
3621 #define NISP_TARG_CMDS          64
3622 #define NISP_TARG_NOTIFIES      64
3623 #define DISK_SHIFT              9
3624 #define JUNK_SIZE               256
3625 #define MULTI_CCB_DATA_LIM      8192
3626 //#define       MULTI_CCB_DATA_CNT      64
3627 #define MULTI_CCB_DATA_CNT      8
3628
3629 extern u_int vm_kmem_size;
3630 static int ca;
3631 static uint32_t disk_size;
3632 static uint8_t *disk_data = NULL;
3633 static uint8_t *junk_data;
3634 static MALLOC_DEFINE(M_ISPTARG, "ISPTARG", "ISP TARGET data");
3635 struct isptarg_softc {
3636         /* CCBs (CTIOs, ATIOs, INOTs) pending on the controller */
3637         struct isp_ccbq         work_queue;
3638         struct isp_ccbq         rework_queue;
3639         struct isp_ccbq         running_queue;
3640         struct isp_ccbq         inot_queue;
3641         struct cam_periph       *periph;
3642         struct cam_path         *path;
3643         ispsoftc_t              *isp;
3644 };
3645 static periph_ctor_t    isptargctor;
3646 static periph_dtor_t    isptargdtor;
3647 static periph_start_t   isptargstart;
3648 static periph_init_t    isptarginit;
3649 static void             isptarg_done(struct cam_periph *, union ccb *);
3650 static void             isptargasync(void *, u_int32_t, struct cam_path *, void *);
3651
3652
3653 static int isptarg_rwparm(uint8_t *, uint8_t *, uint64_t, uint32_t, uint8_t **, uint32_t *, int *);
3654
3655 static struct periph_driver isptargdriver =
3656 {
3657         isptarginit, "isptarg", TAILQ_HEAD_INITIALIZER(isptargdriver.units), 0
3658 };
3659
3660 static void
3661 isptarginit(void)
3662 {
3663 }
3664
3665 static void
3666 isptargnotify(ispsoftc_t *isp, union ccb *iccb, struct ccb_immediate_notify *inot)
3667 {
3668         struct ccb_notify_acknowledge *ack = &iccb->cna2;
3669
3670         ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, inot->ccb_h.path, "%s: [0x%x] immediate notify for 0x%x from 0x%x status 0x%x arg 0x%x\n", __func__,
3671             inot->tag_id, inot->initiator_id, inot->seq_id, inot->ccb_h.status, inot->arg);
3672         ack->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE;
3673         ack->ccb_h.flags = 0;
3674         ack->ccb_h.retry_count = 0;
3675         ack->ccb_h.cbfcnp = isptarg_done;
3676         ack->ccb_h.timeout = 0;
3677         ack->ccb_h.ccb_inot = inot;
3678         ack->tag_id = inot->tag_id;
3679         ack->seq_id = inot->seq_id;
3680         ack->initiator_id = inot->initiator_id;
3681         xpt_action(iccb);
3682 }
3683
3684 static void
3685 isptargstart(struct cam_periph *periph, union ccb *iccb)
3686 {
3687         const uint8_t niliqd[SHORT_INQUIRY_LENGTH] = {
3688                 0x7f, 0x0, 0x5, 0x2, 32, 0, 0, 0x32,
3689                 'F', 'R', 'E', 'E', 'B', 'S', 'D', ' ',
3690                 'S', 'C', 'S', 'I', ' ', 'N', 'U', 'L',
3691                 'L', ' ', 'D', 'E', 'V', 'I', 'C', 'E',
3692                 '0', '0', '0', '1'
3693         };
3694         const uint8_t iqd[SHORT_INQUIRY_LENGTH] = {
3695                 0, 0x0, 0x5, 0x2, 32, 0, 0, 0x32,
3696                 'F', 'R', 'E', 'E', 'B', 'S', 'D', ' ',
3697                 'S', 'C', 'S', 'I', ' ', 'M', 'E', 'M',
3698                 'O', 'R', 'Y', ' ', 'D', 'I', 'S', 'K',
3699                 '0', '0', '0', '1'
3700         };
3701         int r, i, more = 0, last, is_data_cmd = 0, is_write;
3702         char *queue;
3703         struct isptarg_softc *softc = periph->softc;
3704         struct ccb_scsiio *csio;
3705         lun_id_t return_lun;
3706         struct ccb_accept_tio *atio;
3707         uint8_t *cdb, *ptr, status;
3708         uint8_t *data_ptr;
3709         uint32_t data_len, flags;
3710         struct ccb_hdr *ccbh;
3711             
3712         mtx_assert(periph->sim->mtx, MA_OWNED);
3713         ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG1, iccb->ccb_h.path, "%s: function code 0x%x INOTQ=%c WORKQ=%c REWORKQ=%c\n", __func__, iccb->ccb_h.func_code,
3714             TAILQ_FIRST(&softc->inot_queue)? 'y' : 'n', TAILQ_FIRST(&softc->work_queue)? 'y' : 'n', TAILQ_FIRST(&softc->rework_queue)? 'y' : 'n');
3715         /*
3716          * Check for immediate notifies first
3717          */
3718         ccbh = TAILQ_FIRST(&softc->inot_queue);
3719         if (ccbh) {
3720                 TAILQ_REMOVE(&softc->inot_queue, ccbh, periph_links.tqe);
3721                 if (TAILQ_FIRST(&softc->inot_queue) || TAILQ_FIRST(&softc->work_queue) || TAILQ_FIRST(&softc->rework_queue)) {
3722                         xpt_schedule(periph, 1);
3723                 }
3724                 isptargnotify(softc->isp, iccb, (struct ccb_immediate_notify *)ccbh);
3725                 return;
3726         }
3727
3728         /*
3729          * Check the rework (continuation) work queue first.
3730          */
3731         ccbh = TAILQ_FIRST(&softc->rework_queue);
3732         if (ccbh) {
3733                 atio = (struct ccb_accept_tio *)ccbh;
3734                 TAILQ_REMOVE(&softc->rework_queue, ccbh, periph_links.tqe);
3735                 more = TAILQ_FIRST(&softc->work_queue) || TAILQ_FIRST(&softc->rework_queue);
3736                 queue = "rework";
3737         } else {
3738                 ccbh = TAILQ_FIRST(&softc->work_queue);
3739                 if (ccbh == NULL) {
3740                         xpt_release_ccb(iccb);
3741                         return;
3742                 }
3743                 atio = (struct ccb_accept_tio *)ccbh;
3744                 TAILQ_REMOVE(&softc->work_queue, ccbh, periph_links.tqe);
3745                 more = TAILQ_FIRST(&softc->work_queue) != NULL;
3746                 queue = "work";
3747         }
3748         ATIO_PPD(atio)->on_queue = 0;
3749
3750         if (atio->tag_id == 0xffffffff || atio->ccb_h.func_code != XPT_ACCEPT_TARGET_IO) {
3751                 panic("BAD ATIO");
3752         }
3753
3754         data_len = is_write = 0;
3755         data_ptr = NULL;
3756         csio = &iccb->csio;
3757         status = SCSI_STATUS_OK;
3758         flags = CAM_SEND_STATUS;
3759         memset(&atio->sense_data, 0, sizeof (atio->sense_data));
3760         cdb = atio->cdb_io.cdb_bytes;
3761         ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, ccbh->path, "%s: [0x%x] processing ATIO from %s queue initiator 0x%x CDB=0x%x data_offset=%u\n", __func__, atio->tag_id,
3762             queue, atio->init_id, cdb[0], ATIO_PPD(atio)->offset);
3763
3764         return_lun = XS_LUN(atio);
3765         if (return_lun != 0) {
3766                 xpt_print(atio->ccb_h.path, "[0x%x] Non-Zero Lun %d: cdb0=0x%x\n", atio->tag_id, return_lun, cdb[0]);
3767                 if (cdb[0] != INQUIRY && cdb[0] != REPORT_LUNS && cdb[0] != REQUEST_SENSE) {
3768                         status = SCSI_STATUS_CHECK_COND;
3769                         SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR;
3770                         SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST;
3771                         SDFIXED(atio->sense_data)->add_sense_code = 0x25;       /* LOGICAL UNIT NOT SUPPORTED */
3772                         atio->sense_len = SSD_MIN_SIZE;
3773                 }
3774                 return_lun = CAM_LUN_WILDCARD;
3775         }
3776
3777         switch (cdb[0]) {
3778         case REQUEST_SENSE:
3779                 flags |= CAM_DIR_IN;
3780                 data_len = sizeof (atio->sense_data);
3781                 junk_data[0] = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_NO_SENSE;
3782                 memset(junk_data+1, 0, data_len-1);
3783                 if (data_len > cdb[4]) {
3784                         data_len = cdb[4];
3785                 }
3786                 if (data_len) {
3787                         data_ptr = junk_data;
3788                 }
3789                 break;
3790         case WRITE_6:
3791         case WRITE_10:
3792         case WRITE_12:
3793         case WRITE_16:
3794                 is_write = 1;
3795                 /* FALLTHROUGH */
3796         case READ_6:
3797         case READ_10:
3798         case READ_12:
3799         case READ_16:
3800                 is_data_cmd = 1;
3801                 r = isptarg_rwparm(cdb, disk_data, disk_size, ATIO_PPD(atio)->offset, &data_ptr, &data_len, &last);
3802                 if (r != 0) {
3803                         status = SCSI_STATUS_CHECK_COND;
3804                         SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR;
3805                         SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST;
3806                         if (r == -1) {
3807                                 SDFIXED(atio->sense_data)->add_sense_code = 0x21;       /* LOGICAL BLOCK ADDRESS OUT OF RANGE */
3808                         } else {
3809                                 SDFIXED(atio->sense_data)->add_sense_code = 0x20;       /* INVALID COMMAND OPERATION CODE */
3810                         }
3811                         atio->sense_len = SSD_MIN_SIZE;
3812                 } else {
3813 #ifdef  ISP_SEPARATE_STATUS
3814                         if (last && data_len) {
3815                                 last = 0;
3816                         }
3817 #endif
3818                         if (last == 0) {
3819                                 flags &= ~CAM_SEND_STATUS;
3820                         }
3821                         if (data_len) {
3822                                 ATIO_PPD(atio)->offset += data_len;
3823                                 if (is_write)
3824                                         flags |= CAM_DIR_OUT;
3825                                 else
3826                                         flags |= CAM_DIR_IN;
3827                         } else {
3828                                 flags |= CAM_DIR_NONE;
3829                         }
3830                 }
3831                 break;
3832         case INQUIRY:
3833                 flags |= CAM_DIR_IN;
3834                 if (cdb[1] || cdb[2] || cdb[3]) {
3835                         status = SCSI_STATUS_CHECK_COND;
3836                         SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR;
3837                         SDFIXED(atio->sense_data)->flags = SSD_KEY_UNIT_ATTENTION;
3838                         SDFIXED(atio->sense_data)->add_sense_code = 0x24;       /* INVALID FIELD IN CDB */
3839                         atio->sense_len = SSD_MIN_SIZE;
3840                         break;
3841                 }
3842                 data_len = sizeof (iqd);
3843                 if (data_len > cdb[4]) {
3844                         data_len = cdb[4];
3845                 }
3846                 if (data_len) {
3847                         if (XS_LUN(iccb) != 0) {
3848                                 memcpy(junk_data, niliqd, sizeof (iqd));
3849                         } else {
3850                                 memcpy(junk_data, iqd, sizeof (iqd));
3851                         }
3852                         data_ptr = junk_data;
3853                 }
3854                 break;
3855         case TEST_UNIT_READY:
3856                 flags |= CAM_DIR_NONE;
3857                 if (ca) {
3858                         ca = 0;
3859                         status = SCSI_STATUS_CHECK_COND;
3860                         SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR;
3861                         SDFIXED(atio->sense_data)->flags = SSD_KEY_UNIT_ATTENTION;
3862                         SDFIXED(atio->sense_data)->add_sense_code = 0x29;       /* POWER ON, RESET, OR BUS DEVICE RESET OCCURRED */
3863                         atio->sense_len = SSD_MIN_SIZE;
3864                 }
3865                 break;
3866         case SYNCHRONIZE_CACHE:
3867         case START_STOP:
3868         case RESERVE:
3869         case RELEASE:
3870         case VERIFY_10:
3871                 flags |= CAM_DIR_NONE;
3872                 break;
3873
3874         case READ_CAPACITY:
3875                 flags |= CAM_DIR_IN;
3876                 if (cdb[2] || cdb[3] || cdb[4] || cdb[5]) {
3877                         status = SCSI_STATUS_CHECK_COND;
3878                         SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR;
3879                         SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST;
3880                         SDFIXED(atio->sense_data)->add_sense_code =  0x24;      /* INVALID FIELD IN CDB */
3881                         atio->sense_len = SSD_MIN_SIZE;
3882                         break;
3883                 }
3884                 if (cdb[8] & 0x1) { /* PMI */
3885                         junk_data[0] = 0xff;
3886                         junk_data[1] = 0xff;
3887                         junk_data[2] = 0xff;
3888                         junk_data[3] = 0xff;
3889                 } else {
3890                         uint64_t last_blk = (disk_size >> DISK_SHIFT) - 1;
3891                         if (last_blk < 0xffffffffULL) {
3892                             junk_data[0] = (last_blk >> 24) & 0xff;
3893                             junk_data[1] = (last_blk >> 16) & 0xff;
3894                             junk_data[2] = (last_blk >>  8) & 0xff;
3895                             junk_data[3] = (last_blk) & 0xff;
3896                         } else {
3897                             junk_data[0] = 0xff;
3898                             junk_data[1] = 0xff;
3899                             junk_data[2] = 0xff;
3900                             junk_data[3] = 0xff;
3901                         }
3902                 }
3903                 junk_data[4] = ((1 << DISK_SHIFT) >> 24) & 0xff;
3904                 junk_data[5] = ((1 << DISK_SHIFT) >> 16) & 0xff;
3905                 junk_data[6] = ((1 << DISK_SHIFT) >>  8) & 0xff;
3906                 junk_data[7] = ((1 << DISK_SHIFT)) & 0xff;
3907                 data_ptr = junk_data;
3908                 data_len = 8;
3909                 break;
3910         case REPORT_LUNS:
3911                 flags |= CAM_DIR_IN;
3912                 memset(junk_data, 0, JUNK_SIZE);
3913                 junk_data[0] = (1 << 3) >> 24;
3914                 junk_data[1] = (1 << 3) >> 16;
3915                 junk_data[2] = (1 << 3) >> 8;
3916                 junk_data[3] = (1 << 3);
3917                 ptr = NULL;
3918                 for (i = 0; i < 1; i++) {
3919                         ptr = &junk_data[8 + (i << 3)];
3920                         if (i >= 256) {
3921                                 ptr[0] = 0x40 | ((i >> 8) & 0x3f);
3922                         }
3923                         ptr[1] = i;
3924                 }
3925                 data_ptr = junk_data;
3926                 data_len = (ptr + 8) - junk_data;
3927                 break;
3928
3929         default:
3930                 flags |= CAM_DIR_NONE;
3931                 status = SCSI_STATUS_CHECK_COND;
3932                 SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR;
3933                 SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST;
3934                 SDFIXED(atio->sense_data)->add_sense_code = 0x20;       /* INVALID COMMAND OPERATION CODE */
3935                 atio->sense_len = SSD_MIN_SIZE;
3936                 break;
3937         }
3938
3939         /*
3940          * If we are done with the transaction, tell the
3941          * controller to send status and perform a CMD_CMPLT.
3942          * If we have associated sense data, see if we can
3943          * send that too.
3944          */
3945         if (status == SCSI_STATUS_CHECK_COND) {
3946                 flags |= CAM_SEND_SENSE;
3947                 csio->sense_len = atio->sense_len;
3948                 csio->sense_data = atio->sense_data;
3949                 flags &= ~CAM_DIR_MASK;
3950                 data_len = 0;
3951                 data_ptr = NULL;
3952         }
3953         cam_fill_ctio(csio, 0, isptarg_done, flags, MSG_SIMPLE_Q_TAG, atio->tag_id, atio->init_id, status, data_ptr, data_len, 30 * hz);
3954         iccb->ccb_h.target_id = atio->ccb_h.target_id;
3955         iccb->ccb_h.target_lun = return_lun;
3956         iccb->ccb_h.ccb_atio = atio;
3957         CTIO_SEQ(iccb) = ATIO_PPD(atio)->sequence++;
3958         ATIO_PPD(atio)->ctio_cnt++;
3959         if (flags & CAM_SEND_STATUS) {
3960                 KASSERT((ATIO_PPD(atio)->status_sent == 0), ("we have already sent status for 0x%x in %s", atio->tag_id, __func__));
3961                 ATIO_PPD(atio)->status_sent = 1;
3962         }
3963         ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, atio->ccb_h.path, "%s: sending downstream for  0x%x sequence %u len %u flags %x\n", __func__, atio->tag_id, CTIO_SEQ(iccb), data_len, flags);
3964         xpt_action(iccb);
3965
3966         if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3967                 cam_release_devq(periph->path, 0, 0, 0, 0); 
3968                 atio->ccb_h.status &= ~CAM_DEV_QFRZN;
3969         }
3970 #ifdef  ISP_MULTI_CCBS
3971         if (is_data_cmd && ATIO_PPD(atio)->status_sent == 0 && ATIO_PPD(atio)->ctio_cnt < MULTI_CCB_DATA_CNT && ATIO_PPD(atio)->on_queue == 0) {
3972                 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, atio->ccb_h.path, "%s: more still to do for 0x%x\n", __func__, atio->tag_id);
3973                 TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe); 
3974                 ATIO_PPD(atio)->on_queue = 1;
3975                 more = 1;
3976         }
3977 #endif
3978         if (more) {
3979                 xpt_schedule(periph, 1);
3980         }
3981 }
3982
3983 static cam_status
3984 isptargctor(struct cam_periph *periph, void *arg)
3985 {
3986         struct isptarg_softc *softc;
3987
3988         softc = (struct isptarg_softc *)arg;
3989         periph->softc = softc;
3990         softc->periph = periph;
3991         softc->path = periph->path;
3992         ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG1, periph->path, "%s called\n", __func__);
3993         return (CAM_REQ_CMP);
3994 }
3995
3996 static void
3997 isptargdtor(struct cam_periph *periph)
3998 {
3999         struct isptarg_softc *softc;
4000         softc = (struct isptarg_softc *)periph->softc;
4001         ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG1, periph->path, "%s called\n", __func__);
4002         softc->periph = NULL;
4003         softc->path = NULL;
4004         periph->softc = NULL;
4005 }
4006
4007 static void
4008 isptarg_done(struct cam_periph *periph, union ccb *ccb)
4009 {
4010         struct isptarg_softc *softc;
4011         ispsoftc_t *isp;
4012         uint32_t newoff;
4013         struct ccb_accept_tio *atio;
4014         struct ccb_immediate_notify *inot;
4015         cam_status status;
4016
4017         softc = (struct isptarg_softc *)periph->softc;
4018         isp = softc->isp;
4019         status = ccb->ccb_h.status & CAM_STATUS_MASK;
4020
4021         switch (ccb->ccb_h.func_code) {
4022         case XPT_ACCEPT_TARGET_IO:
4023                 atio = (struct ccb_accept_tio *) ccb;
4024                 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] ATIO seen in %s\n", atio->tag_id, __func__);
4025                 memset(ATIO_PPD(atio), 0, sizeof (ppd_t));
4026                 TAILQ_INSERT_TAIL(&softc->work_queue, &ccb->ccb_h, periph_links.tqe); 
4027                 ATIO_PPD(atio)->on_queue = 1;
4028                 xpt_schedule(periph, 1);
4029                 break;
4030         case XPT_IMMEDIATE_NOTIFY:
4031                 inot = (struct ccb_immediate_notify *) ccb;
4032                 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] INOT for 0x%x seen in %s\n", inot->tag_id, inot->seq_id, __func__);
4033                 TAILQ_INSERT_TAIL(&softc->inot_queue, &ccb->ccb_h, periph_links.tqe); 
4034                 xpt_schedule(periph, 1);
4035                 break;
4036         case XPT_CONT_TARGET_IO:
4037                 atio = ccb->ccb_h.ccb_atio;
4038                 KASSERT((ATIO_PPD(atio)->ctio_cnt != 0), ("ctio zero when finishing a CTIO"));
4039                 ATIO_PPD(atio)->ctio_cnt--;
4040                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4041                         switch (ccb->ccb_h.status & CAM_STATUS_MASK) {
4042                         case CAM_MESSAGE_RECV:
4043                                 newoff = (ccb->csio.msg_ptr[3] << 24) | (ccb->csio.msg_ptr[4] << 16) | (ccb->csio.msg_ptr[5] << 8) | (ccb->csio.msg_ptr[6]);
4044                                 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "[0x%x] got message to return to reset offset to 0x%x at sequence %u\n", atio->tag_id, newoff, CTIO_SEQ(ccb));
4045                                 ATIO_PPD(atio)->offset = newoff;
4046                                 ATIO_PPD(atio)->status_sent = 0;
4047                                 if (ATIO_PPD(atio)->on_queue == 0) {
4048                                         TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe); 
4049                                         ATIO_PPD(atio)->on_queue = 1;
4050                                 }
4051                                 xpt_schedule(periph, 1);
4052                                 break;
4053                         default:
4054                                 cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL);
4055                                 xpt_action((union ccb *)atio);
4056                                 break;
4057                         }
4058                 } else if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) {
4059                         ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] MID CTIO sequence %u seen in %s\n", atio->tag_id, CTIO_SEQ(ccb), __func__);
4060                         if (ATIO_PPD(atio)->status_sent == 0 && ATIO_PPD(atio)->on_queue == 0) {
4061                                 TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe); 
4062                                 ATIO_PPD(atio)->on_queue = 1;
4063                         }
4064                         xpt_schedule(periph, 1);
4065                 } else {
4066                         KASSERT((ATIO_PPD(atio)->ctio_cnt == 0), ("ctio count still %d when we think we've sent the STATUS ctio", ATIO_PPD(atio)->ctio_cnt));
4067                         ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] FINAL CTIO sequence %u seen in %s\n", atio->tag_id, CTIO_SEQ(ccb), __func__);
4068                         xpt_action((union ccb *)atio);
4069                 }
4070                 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
4071                         cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0); 
4072                         ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
4073                 }
4074                 xpt_release_ccb(ccb);
4075                 break;
4076         case XPT_NOTIFY_ACKNOWLEDGE:
4077                 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
4078                         cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0); 
4079                         ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
4080                 }
4081                 inot = ccb->ccb_h.ccb_inot;
4082                 ISP_PATH_PRT(isp, ISP_LOGTDEBUG1, inot->ccb_h.path, "[0x%x] recycle notify for tag 0x%x\n", inot->tag_id, inot->seq_id);
4083                 xpt_release_ccb(ccb);
4084                 xpt_action((union ccb *)inot);
4085                 break;
4086         default:
4087                 xpt_print(ccb->ccb_h.path, "unexpected code 0x%x\n", ccb->ccb_h.func_code);
4088                 break;
4089         }
4090 }
4091
4092 static void
4093 isptargasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
4094 {
4095         struct ac_contract *acp = arg;
4096         struct ac_device_changed *fc = (struct ac_device_changed *) acp->contract_data;
4097
4098         if (code != AC_CONTRACT) {
4099                 return;
4100         }
4101         xpt_print(path, "0x%016llx Port ID 0x%06x %s\n", (unsigned long long) fc->wwpn, fc->port, fc->arrived? "arrived" : "departed");
4102 }
4103
4104 static void
4105 isp_target_thread(ispsoftc_t *isp, int chan)
4106 {
4107         union ccb *ccb = NULL;
4108         int i;
4109         void *wchan;
4110         cam_status status;
4111         struct isptarg_softc *softc = NULL;
4112         struct cam_periph *periph = NULL, *wperiph = NULL;
4113         struct cam_path *path, *wpath;
4114         struct cam_sim *sim;
4115
4116         if (disk_data == NULL) {
4117                 disk_size = roundup2(vm_kmem_size >> 1, (1ULL << 20));
4118                 if (disk_size < (50 << 20)) {
4119                         disk_size = 50 << 20;
4120                 }
4121                 disk_data = malloc(disk_size, M_ISPTARG, M_WAITOK | M_ZERO);
4122                 if (disk_data == NULL) {
4123                         isp_prt(isp, ISP_LOGERR, "%s: could not allocate disk data", __func__);
4124                         goto out;
4125                 }
4126                 isp_prt(isp, ISP_LOGINFO, "allocated a %ju MiB disk", (uintmax_t) (disk_size >> 20));
4127         }
4128         junk_data = malloc(JUNK_SIZE, M_ISPTARG, M_WAITOK | M_ZERO);
4129         if (junk_data == NULL) {
4130                 isp_prt(isp, ISP_LOGERR, "%s: could not allocate junk", __func__);
4131                 goto out;
4132         }
4133
4134
4135         softc = malloc(sizeof (*softc), M_ISPTARG, M_WAITOK | M_ZERO);
4136         if (softc == NULL) {
4137                 isp_prt(isp, ISP_LOGERR, "%s: could not allocate softc", __func__);
4138                 goto out;
4139         }
4140         TAILQ_INIT(&softc->work_queue);
4141         TAILQ_INIT(&softc->rework_queue);
4142         TAILQ_INIT(&softc->running_queue);
4143         TAILQ_INIT(&softc->inot_queue);
4144         softc->isp = isp;
4145
4146         periphdriver_register(&isptargdriver);
4147         ISP_GET_PC(isp, chan, sim, sim);
4148         ISP_GET_PC(isp, chan, path,  path);
4149         status = xpt_create_path(&wpath, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
4150         if (status != CAM_REQ_CMP) {
4151                 isp_prt(isp, ISP_LOGERR, "%s: could not allocate wildcard path", __func__);
4152                 return;
4153         }
4154         status = xpt_create_path(&path, NULL, cam_sim_path(sim), 0, 0);
4155         if (status != CAM_REQ_CMP) {
4156                 xpt_free_path(wpath);
4157                 isp_prt(isp, ISP_LOGERR, "%s: could not allocate path", __func__);
4158                 return;
4159         }
4160
4161         ISP_LOCK(isp);
4162         status = cam_periph_alloc(isptargctor, NULL, isptargdtor, isptargstart, "isptarg", CAM_PERIPH_BIO, wpath, NULL, 0, softc);
4163         if (status != CAM_REQ_CMP) {
4164                 ISP_UNLOCK(isp);
4165                 isp_prt(isp, ISP_LOGERR, "%s: cam_periph_alloc for wildcard failed", __func__);
4166                 goto out;
4167         }
4168         wperiph = cam_periph_find(wpath, "isptarg");
4169         if (wperiph == NULL) {
4170                 ISP_UNLOCK(isp);
4171                 isp_prt(isp, ISP_LOGERR, "%s: wildcard periph already allocated but doesn't exist", __func__);
4172                 goto out;
4173         }
4174
4175         status = cam_periph_alloc(isptargctor, NULL, isptargdtor, isptargstart, "isptarg", CAM_PERIPH_BIO, path, NULL, 0, softc);
4176         if (status != CAM_REQ_CMP) {
4177                 ISP_UNLOCK(isp);
4178                 isp_prt(isp, ISP_LOGERR, "%s: cam_periph_alloc failed", __func__);
4179                 goto out;
4180         }
4181
4182         periph = cam_periph_find(path, "isptarg");
4183         if (periph == NULL) {
4184                 ISP_UNLOCK(isp);
4185                 isp_prt(isp, ISP_LOGERR, "%s: periph already allocated but doesn't exist", __func__);
4186                 goto out;
4187         }
4188
4189         status = xpt_register_async(AC_CONTRACT, isptargasync, isp, wpath);
4190         if (status != CAM_REQ_CMP) {
4191                 ISP_UNLOCK(isp);
4192                 isp_prt(isp, ISP_LOGERR, "%s: xpt_register_async failed", __func__);
4193                 goto out;
4194         }
4195
4196         ISP_UNLOCK(isp);
4197
4198         ccb = xpt_alloc_ccb();
4199
4200         /*
4201          * Make sure role is none.
4202          */
4203         xpt_setup_ccb(&ccb->ccb_h, periph->path, 10);
4204         ccb->ccb_h.func_code = XPT_SET_SIM_KNOB;
4205         ccb->knob.xport_specific.fc.role = KNOB_ROLE_NONE;
4206         ccb->knob.xport_specific.fc.valid = KNOB_VALID_ROLE;
4207
4208         ISP_LOCK(isp);
4209         xpt_action(ccb);
4210         ISP_UNLOCK(isp);
4211
4212         /*
4213          * Now enable luns
4214          */
4215         xpt_setup_ccb(&ccb->ccb_h, periph->path, 10);
4216         ccb->ccb_h.func_code = XPT_EN_LUN;
4217         ccb->cel.enable = 1;
4218         ISP_LOCK(isp);
4219         xpt_action(ccb);
4220         ISP_UNLOCK(isp);
4221         if (ccb->ccb_h.status != CAM_REQ_CMP) {
4222                 xpt_free_ccb(ccb);
4223                 xpt_print(periph->path, "failed to enable lun (0x%x)\n", ccb->ccb_h.status);
4224                 goto out;
4225         }
4226
4227         xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 10);
4228         ccb->ccb_h.func_code = XPT_EN_LUN;
4229         ccb->cel.enable = 1;
4230         ISP_LOCK(isp);
4231         xpt_action(ccb);
4232         ISP_UNLOCK(isp);
4233         if (ccb->ccb_h.status != CAM_REQ_CMP) {
4234                 xpt_free_ccb(ccb);
4235                 xpt_print(wperiph->path, "failed to enable lun (0x%x)\n", ccb->ccb_h.status);
4236                 goto out;
4237         }
4238         xpt_free_ccb(ccb);
4239
4240         /*
4241          * Add resources
4242          */
4243         ISP_GET_PC(isp, chan, target_proc, wchan);
4244         for (i = 0; i < 4; i++) {
4245                 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO);
4246                 xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 1);
4247                 ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
4248                 ccb->ccb_h.cbfcnp = isptarg_done;
4249                 ccb->ccb_h.ppriv_ptr0 = malloc(sizeof (ppd_t), M_ISPTARG, M_WAITOK | M_ZERO);
4250                 ISP_LOCK(isp);
4251                 xpt_action(ccb);
4252                 ISP_UNLOCK(isp);
4253         }
4254         for (i = 0; i < NISP_TARG_CMDS; i++) {
4255                 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO);
4256                 xpt_setup_ccb(&ccb->ccb_h, periph->path, 1);
4257                 ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
4258                 ccb->ccb_h.cbfcnp = isptarg_done;
4259                 ccb->ccb_h.ppriv_ptr0 = malloc(sizeof (ppd_t), M_ISPTARG, M_WAITOK | M_ZERO);
4260                 ISP_LOCK(isp);
4261                 xpt_action(ccb);
4262                 ISP_UNLOCK(isp);
4263         }
4264         for (i = 0; i < 4; i++) {
4265                 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO);
4266                 xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 1);
4267                 ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
4268                 ccb->ccb_h.cbfcnp = isptarg_done;
4269                 ISP_LOCK(isp);
4270                 xpt_action(ccb);
4271                 ISP_UNLOCK(isp);
4272         }
4273         for (i = 0; i < NISP_TARG_NOTIFIES; i++) {
4274                 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO);
4275                 xpt_setup_ccb(&ccb->ccb_h, periph->path, 1);
4276                 ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
4277                 ccb->ccb_h.cbfcnp = isptarg_done;
4278                 ISP_LOCK(isp);
4279                 xpt_action(ccb);
4280                 ISP_UNLOCK(isp);
4281         }
4282
4283         /*
4284          * Now turn it all back on
4285          */
4286         xpt_setup_ccb(&ccb->ccb_h, periph->path, 10);
4287         ccb->ccb_h.func_code = XPT_SET_SIM_KNOB;
4288         ccb->knob.xport_specific.fc.valid = KNOB_VALID_ROLE;
4289         ccb->knob.xport_specific.fc.role = KNOB_ROLE_TARGET;
4290         ISP_LOCK(isp);
4291         xpt_action(ccb);
4292         ISP_UNLOCK(isp);
4293
4294         /*
4295          * Okay, while things are still active, sleep...
4296          */
4297         ISP_LOCK(isp);
4298         for (;;) {
4299                 ISP_GET_PC(isp, chan, proc_active, i);
4300                 if (i == 0) {
4301                         break;
4302                 }
4303                 msleep(wchan, &isp->isp_lock, PUSER, "tsnooze", 0);
4304         }
4305         ISP_UNLOCK(isp);
4306
4307 out:
4308         if (wperiph) {
4309                 cam_periph_invalidate(wperiph);
4310         }
4311         if (periph) {
4312                 cam_periph_invalidate(periph);
4313         }
4314         if (junk_data) {
4315                 free(junk_data, M_ISPTARG);
4316         }
4317         if (disk_data) {
4318                 free(disk_data, M_ISPTARG);
4319         }
4320         if (softc) {
4321                 free(softc, M_ISPTARG);
4322         }
4323         xpt_free_path(path);
4324         xpt_free_path(wpath);
4325 }
4326
4327 static void
4328 isp_target_thread_pi(void *arg)
4329 {
4330         struct isp_spi *pi = arg;
4331         ispsoftc_t *isp = cam_sim_softc(pi->sim);
4332         int chan = cam_sim_bus(pi->sim);
4333
4334         isp_target_thread(isp, chan);
4335         ISP_SPI_PC(isp, chan)->num_threads -= 1;
4336         kthread_exit();
4337 }
4338
4339 static void
4340 isp_target_thread_fc(void *arg)
4341 {
4342         struct isp_fc *fc = arg;
4343         ispsoftc_t *isp = cam_sim_softc(pi->sim);
4344         int chan = cam_sim_bus(pi->sim);
4345
4346         isp_target_thread(isp, chan);
4347         ISP_FC_PC(isp, chan)->num_threads -= 1;
4348         kthread_exit();
4349 }
4350
4351 static int
4352 isptarg_rwparm(uint8_t *cdb, uint8_t *dp, uint64_t dl, uint32_t offset, uint8_t **kp, uint32_t *tl, int *lp)
4353 {
4354         uint32_t cnt, curcnt;
4355         uint64_t lba;
4356
4357         switch (cdb[0]) {
4358         case WRITE_16:
4359         case READ_16:
4360                 cnt =   (((uint32_t)cdb[10]) <<  24) |
4361                         (((uint32_t)cdb[11]) <<  16) |
4362                         (((uint32_t)cdb[12]) <<   8) |
4363                         ((uint32_t)cdb[13]);
4364
4365                 lba =   (((uint64_t)cdb[2]) << 56) |
4366                         (((uint64_t)cdb[3]) << 48) |
4367                         (((uint64_t)cdb[4]) << 40) |
4368                         (((uint64_t)cdb[5]) << 32) |
4369                         (((uint64_t)cdb[6]) << 24) |
4370                         (((uint64_t)cdb[7]) << 16) |
4371                         (((uint64_t)cdb[8]) <<  8) |
4372                         ((uint64_t)cdb[9]);
4373                 break;
4374         case WRITE_12:
4375         case READ_12:
4376                 cnt =   (((uint32_t)cdb[6]) <<  16) |
4377                         (((uint32_t)cdb[7]) <<   8) |
4378                         ((u_int32_t)cdb[8]);
4379
4380                 lba =   (((uint32_t)cdb[2]) << 24) |
4381                         (((uint32_t)cdb[3]) << 16) |
4382                         (((uint32_t)cdb[4]) <<  8) |
4383                         ((uint32_t)cdb[5]);
4384                 break;
4385         case WRITE_10:
4386         case READ_10:
4387                 cnt =   (((uint32_t)cdb[7]) <<  8) |
4388                         ((u_int32_t)cdb[8]);
4389
4390                 lba =   (((uint32_t)cdb[2]) << 24) |
4391                         (((uint32_t)cdb[3]) << 16) |
4392                         (((uint32_t)cdb[4]) <<  8) |
4393                         ((uint32_t)cdb[5]);
4394                 break;
4395         case WRITE_6:
4396         case READ_6:
4397                 cnt = cdb[4];
4398                 if (cnt == 0) {
4399                         cnt = 256;
4400                 }
4401                 lba =   (((uint32_t)cdb[1] & 0x1f) << 16) |
4402                         (((uint32_t)cdb[2]) << 8) |
4403                         ((uint32_t)cdb[3]);
4404                 break;
4405         default:
4406                 return (-1);
4407         }
4408
4409         cnt <<= DISK_SHIFT;
4410         lba <<= DISK_SHIFT;
4411
4412         if (offset == cnt) {
4413                 *lp = 1;
4414                 return (0);
4415         }
4416
4417         if (lba + cnt > dl) {
4418                 return (-2);
4419         }
4420
4421         curcnt = MAX_ISP_TARG_TRANSFER;
4422         if (offset + curcnt >= cnt) {
4423                 curcnt = cnt - offset;
4424                 *lp = 1;
4425         } else {
4426                 *lp = 0;
4427         }
4428 #ifdef  ISP_MULTI_CCBS
4429         if (curcnt > MULTI_CCB_DATA_LIM)
4430                 curcnt = MULTI_CCB_DATA_LIM;
4431 #endif
4432         *tl = curcnt;
4433         *kp = &dp[lba + offset];
4434         return (0);
4435 }
4436
4437 #endif
4438 #endif
4439
4440 static void
4441 isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
4442 {
4443         struct cam_sim *sim;
4444         int bus, tgt;
4445         ispsoftc_t *isp;
4446
4447         sim = (struct cam_sim *)cbarg;
4448         isp = (ispsoftc_t *) cam_sim_softc(sim);
4449         bus = cam_sim_bus(sim);
4450         tgt = xpt_path_target_id(path);
4451
4452         switch (code) {
4453         case AC_LOST_DEVICE:
4454                 if (IS_SCSI(isp)) {
4455                         uint16_t oflags, nflags;
4456                         sdparam *sdp = SDPARAM(isp, bus);
4457
4458                         if (tgt >= 0) {
4459                                 nflags = sdp->isp_devparam[tgt].nvrm_flags;
4460 #ifndef ISP_TARGET_MODE
4461                                 nflags &= DPARM_SAFE_DFLT;
4462                                 if (isp->isp_loaded_fw) {
4463                                         nflags |= DPARM_NARROW | DPARM_ASYNC;
4464                                 }
4465 #else
4466                                 nflags = DPARM_DEFAULT;
4467 #endif
4468                                 oflags = sdp->isp_devparam[tgt].goal_flags;
4469                                 sdp->isp_devparam[tgt].goal_flags = nflags;
4470                                 sdp->isp_devparam[tgt].dev_update = 1;
4471                                 sdp->update = 1;
4472                                 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus);
4473                                 sdp->isp_devparam[tgt].goal_flags = oflags;
4474                         }
4475                 }
4476                 break;
4477         default:
4478                 isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code);
4479                 break;
4480         }
4481 }
4482
4483 static void
4484 isp_poll(struct cam_sim *sim)
4485 {
4486         ispsoftc_t *isp = cam_sim_softc(sim);
4487         uint32_t isr;
4488         uint16_t sema, mbox;
4489
4490         if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
4491                 isp_intr(isp, isr, sema, mbox);
4492         }
4493 }
4494
4495
4496 static void
4497 isp_watchdog(void *arg)
4498 {
4499         struct ccb_scsiio *xs = arg;
4500         ispsoftc_t *isp;
4501         uint32_t ohandle = ISP_HANDLE_FREE, handle;
4502
4503         isp = XS_ISP(xs);
4504
4505         handle = isp_find_handle(isp, xs);
4506
4507         /*
4508          * Hand crank the interrupt code just to be sure the command isn't stuck somewhere.
4509          */
4510         if (handle != ISP_HANDLE_FREE) {
4511                 uint32_t isr;
4512                 uint16_t sema, mbox;
4513                 if (ISP_READ_ISR(isp, &isr, &sema, &mbox) != 0) {
4514                         isp_intr(isp, isr, sema, mbox);
4515                 }
4516                 ohandle = handle;
4517                 handle = isp_find_handle(isp, xs);
4518         }
4519         if (handle != ISP_HANDLE_FREE) {
4520                 /*
4521                  * Try and make sure the command is really dead before
4522                  * we release the handle (and DMA resources) for reuse.
4523                  *
4524                  * If we are successful in aborting the command then
4525                  * we're done here because we'll get the command returned
4526                  * back separately.
4527                  */
4528                 if (isp_control(isp, ISPCTL_ABORT_CMD, xs) == 0) {
4529                         return;
4530                 }
4531
4532                 /*
4533                  * Note that after calling the above, the command may in
4534                  * fact have been completed.
4535                  */
4536                 xs = isp_find_xs(isp, handle);
4537
4538                 /*
4539                  * If the command no longer exists, then we won't
4540                  * be able to find the xs again with this handle.
4541                  */
4542                 if (xs == NULL) {
4543                         return;
4544                 }
4545
4546                 /*
4547                  * After this point, the command is really dead.
4548                  */
4549                 if (XS_XFRLEN(xs)) {
4550                         ISP_DMAFREE(isp, xs, handle);
4551                 } 
4552                 isp_destroy_handle(isp, handle);
4553                 isp_prt(isp, ISP_LOGERR, "%s: timeout for handle 0x%x", __func__, handle);
4554                 xs->ccb_h.status &= ~CAM_STATUS_MASK;
4555                 xs->ccb_h.status |= CAM_CMD_TIMEOUT;
4556                 isp_prt_endcmd(isp, xs);
4557                 isp_done(xs);
4558         } else {
4559                 if (ohandle != ISP_HANDLE_FREE) {
4560                         isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle 0x%x, recovered during interrupt", __func__, ohandle);
4561                 } else {
4562                         isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle already free", __func__);
4563                 }
4564         }
4565 }
4566
4567 static void
4568 isp_make_here(ispsoftc_t *isp, int chan, int tgt)
4569 {
4570         union ccb *ccb;
4571         struct isp_fc *fc = ISP_FC_PC(isp, chan);
4572
4573         if (isp_autoconfig == 0) {
4574                 return;
4575         }
4576
4577         /*
4578          * Allocate a CCB, create a wildcard path for this target and schedule a rescan.
4579          */
4580         ccb = xpt_alloc_ccb_nowait();
4581         if (ccb == NULL) {
4582                 isp_prt(isp, ISP_LOGWARN, "Chan %d unable to alloc CCB for rescan", chan);
4583                 return;
4584         }
4585         if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(fc->sim),
4586             tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
4587                 isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
4588                 xpt_free_ccb(ccb);
4589                 return;
4590         }
4591         xpt_rescan(ccb);
4592 }
4593
4594 static void
4595 isp_make_gone(ispsoftc_t *isp, int chan, int tgt)
4596 {
4597         struct cam_path *tp;
4598         struct isp_fc *fc = ISP_FC_PC(isp, chan);
4599
4600         if (isp_autoconfig == 0) {
4601                 return;
4602         }
4603         if (xpt_create_path(&tp, NULL, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
4604                 xpt_async(AC_LOST_DEVICE, tp, NULL);
4605                 xpt_free_path(tp);
4606         }
4607 }
4608
4609 /*
4610  * Gone Device Timer Function- when we have decided that a device has gone
4611  * away, we wait a specific period of time prior to telling the OS it has
4612  * gone away.
4613  *
4614  * This timer function fires once a second and then scans the port database
4615  * for devices that are marked dead but still have a virtual target assigned.
4616  * We decrement a counter for that port database entry, and when it hits zero,
4617  * we tell the OS the device has gone away.
4618  */
4619 static void
4620 isp_gdt(void *arg)
4621 {
4622         struct isp_fc *fc = arg;
4623         taskqueue_enqueue(taskqueue_thread, &fc->gtask);
4624 }
4625
4626 static void
4627 isp_gdt_task(void *arg, int pending)
4628 {
4629         struct isp_fc *fc = arg;
4630         ispsoftc_t *isp = fc->isp;
4631         int chan = fc - isp->isp_osinfo.pc.fc;
4632         fcportdb_t *lp;
4633         int dbidx, tgt, more_to_do = 0;
4634
4635         ISP_LOCK(isp);
4636         isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GDT timer expired", chan);
4637         for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
4638                 lp = &FCPARAM(isp, chan)->portdb[dbidx];
4639
4640                 if (lp->state != FC_PORTDB_STATE_ZOMBIE) {
4641                         continue;
4642                 }
4643                 if (lp->dev_map_idx == 0 || lp->target_mode) {
4644                         continue;
4645                 }
4646                 if (lp->gone_timer != 0) {
4647                         isp_prt(isp, ISP_LOG_SANCFG, "%s: Chan %d more to do for target %u (timer=%u)", __func__, chan, lp->dev_map_idx - 1, lp->gone_timer);
4648                         lp->gone_timer -= 1;
4649                         more_to_do++;
4650                         continue;
4651                 }
4652                 tgt = lp->dev_map_idx - 1;
4653                 FCPARAM(isp, chan)->isp_dev_map[tgt] = 0;
4654                 lp->dev_map_idx = 0;
4655                 lp->state = FC_PORTDB_STATE_NIL;
4656                 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, tgt, "Gone Device Timeout");
4657                 isp_make_gone(isp, chan, tgt);
4658         }
4659         if (fc->ready) {
4660                 if (more_to_do) {
4661                         callout_reset(&fc->gdt, hz, isp_gdt, fc);
4662                 } else {
4663                         callout_deactivate(&fc->gdt);
4664                         isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Stopping Gone Device Timer @ %lu", chan, (unsigned long) time_uptime);
4665                 }
4666         }
4667         ISP_UNLOCK(isp);
4668 }
4669
4670 /*
4671  * Loop Down Timer Function- when loop goes down, a timer is started and
4672  * and after it expires we come here and take all probational devices that
4673  * the OS knows about and the tell the OS that they've gone away.
4674  * 
4675  * We don't clear the devices out of our port database because, when loop
4676  * come back up, we have to do some actual cleanup with the chip at that
4677  * point (implicit PLOGO, e.g., to get the chip's port database state right).
4678  */
4679 static void
4680 isp_ldt(void *arg)
4681 {
4682         struct isp_fc *fc = arg;
4683         taskqueue_enqueue(taskqueue_thread, &fc->ltask);
4684 }
4685
4686 static void
4687 isp_ldt_task(void *arg, int pending)
4688 {
4689         struct isp_fc *fc = arg;
4690         ispsoftc_t *isp = fc->isp;
4691         int chan = fc - isp->isp_osinfo.pc.fc;
4692         fcportdb_t *lp;
4693         int dbidx, tgt, i;
4694
4695         ISP_LOCK(isp);
4696         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop Down Timer expired @ %lu", chan, (unsigned long) time_uptime);
4697         callout_deactivate(&fc->ldt);
4698
4699         /*
4700          * Notify to the OS all targets who we now consider have departed.
4701          */
4702         for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
4703                 lp = &FCPARAM(isp, chan)->portdb[dbidx];
4704
4705                 if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
4706                         continue;
4707                 }
4708                 if (lp->dev_map_idx == 0 || lp->target_mode) {
4709                         continue;
4710                 }
4711
4712                 /*
4713                  * XXX: CLEAN UP AND COMPLETE ANY PENDING COMMANDS FIRST!
4714                  */
4715
4716
4717                 for (i = 0; i < isp->isp_maxcmds; i++) {
4718                         struct ccb_scsiio *xs;
4719
4720                         if (!ISP_VALID_HANDLE(isp, isp->isp_xflist[i].handle)) {
4721                                 continue;
4722                         }
4723                         if ((xs = isp->isp_xflist[i].cmd) == NULL) {
4724                                 continue;
4725                         }
4726                         if (dbidx != (FCPARAM(isp, chan)->isp_dev_map[XS_TGT(xs)] - 1)) {
4727                                 continue;
4728                         }
4729                         isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%d orphaned by loop down timeout",
4730                             isp->isp_xflist[i].handle, chan, XS_TGT(xs), XS_LUN(xs));
4731                 }
4732
4733                 /*
4734                  * Mark that we've announced that this device is gone....
4735                  */
4736                 lp->announced = 1;
4737
4738                 /*
4739                  * but *don't* change the state of the entry. Just clear
4740                  * any target id stuff and announce to CAM that the
4741                  * device is gone. This way any necessary PLOGO stuff
4742                  * will happen when loop comes back up.
4743                  */
4744
4745                 tgt = lp->dev_map_idx - 1;
4746                 FCPARAM(isp, chan)->isp_dev_map[tgt] = 0;
4747                 lp->dev_map_idx = 0;
4748                 lp->state = FC_PORTDB_STATE_NIL;
4749                 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, tgt, "Loop Down Timeout");
4750                 isp_make_gone(isp, chan, tgt);
4751         }
4752
4753         if (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR) {
4754                 isp_unfreeze_loopdown(isp, chan);
4755         }
4756         /*
4757          * The loop down timer has expired. Wake up the kthread
4758          * to notice that fact (or make it false).
4759          */
4760         fc->loop_dead = 1;
4761         fc->loop_down_time = fc->loop_down_limit+1;
4762         wakeup(fc);
4763         ISP_UNLOCK(isp);
4764 }
4765
4766 static void
4767 isp_kthread(void *arg)
4768 {
4769         struct isp_fc *fc = arg;
4770         ispsoftc_t *isp = fc->isp;
4771         int chan = fc - isp->isp_osinfo.pc.fc;
4772         int slp = 0;
4773
4774         mtx_lock(&isp->isp_osinfo.lock);
4775
4776         while (isp->isp_osinfo.is_exiting == 0) {
4777                 int lb, lim;
4778
4779                 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d checking FC state", __func__, chan);
4780                 lb = isp_fc_runstate(isp, chan, 250000);
4781
4782                 /*
4783                  * Our action is different based upon whether we're supporting
4784                  * Initiator mode or not. If we are, we might freeze the simq
4785                  * when loop is down and set all sorts of different delays to
4786                  * check again.
4787                  *
4788                  * If not, we simply just wait for loop to come up.
4789                  */
4790                 if (lb && (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR)) {
4791                         /*
4792                          * Increment loop down time by the last sleep interval
4793                          */
4794                         fc->loop_down_time += slp;
4795
4796                         if (lb < 0) {
4797                                 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC loop not up (down count %d)", __func__, chan, fc->loop_down_time);
4798                         } else {
4799                                 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC got to %d (down count %d)", __func__, chan, lb, fc->loop_down_time);
4800                         }
4801
4802                         /*
4803                          * If we've never seen loop up and we've waited longer
4804                          * than quickboot time, or we've seen loop up but we've
4805                          * waited longer than loop_down_limit, give up and go
4806                          * to sleep until loop comes up.
4807                          */
4808                         if (FCPARAM(isp, chan)->loop_seen_once == 0) {
4809                                 lim = isp_quickboot_time;
4810                         } else {
4811                                 lim = fc->loop_down_limit;
4812                         }
4813                         if (fc->loop_down_time >= lim) {
4814                                 isp_freeze_loopdown(isp, chan, "loop limit hit");
4815                                 slp = 0;
4816                         } else if (fc->loop_down_time < 10) {
4817                                 slp = 1;
4818                         } else if (fc->loop_down_time < 30) {
4819                                 slp = 5;
4820                         } else if (fc->loop_down_time < 60) {
4821                                 slp = 10;
4822                         } else if (fc->loop_down_time < 120) {
4823                                 slp = 20;
4824                         } else {
4825                                 slp = 30;
4826                         }
4827
4828                 } else if (lb) {
4829                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC Loop Down", __func__, chan);
4830                         fc->loop_down_time += slp;
4831                         if (fc->loop_down_time > 300)
4832                                 slp = 0;
4833                         else
4834                                 slp = 60;
4835                 } else {
4836                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC state OK", __func__, chan);
4837                         fc->loop_down_time = 0;
4838                         slp = 0;
4839                 }
4840
4841
4842                 /*
4843                  * If this is past the first loop up or the loop is dead and if we'd frozen the simq, unfreeze it
4844                  * now so that CAM can start sending us commands.
4845                  *
4846                  * If the FC state isn't okay yet, they'll hit that in isp_start which will freeze the queue again
4847                  * or kill the commands, as appropriate.
4848                  */
4849
4850                 if (FCPARAM(isp, chan)->loop_seen_once || fc->loop_dead) {
4851                         isp_unfreeze_loopdown(isp, chan);
4852                 }
4853
4854                 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep time %d", __func__, chan, slp);
4855
4856                 msleep(fc, &isp->isp_osinfo.lock, PRIBIO, "ispf", slp * hz);
4857
4858                 /*
4859                  * If slp is zero, we're waking up for the first time after
4860                  * things have been okay. In this case, we set a deferral state
4861                  * for all commands and delay hysteresis seconds before starting
4862                  * the FC state evaluation. This gives the loop/fabric a chance
4863                  * to settle.
4864                  */
4865                 if (slp == 0 && fc->hysteresis) {
4866                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep hysteresis ticks %d", __func__, chan, fc->hysteresis * hz);
4867                         mtx_unlock(&isp->isp_osinfo.lock);
4868                         pause("ispt", fc->hysteresis * hz);
4869                         mtx_lock(&isp->isp_osinfo.lock);
4870                 }
4871         }
4872         fc->num_threads -= 1;
4873         mtx_unlock(&isp->isp_osinfo.lock);
4874         kthread_exit();
4875 }
4876
4877 static void
4878 isp_action(struct cam_sim *sim, union ccb *ccb)
4879 {
4880         int bus, tgt, ts, error, lim;
4881         ispsoftc_t *isp;
4882         struct ccb_trans_settings *cts;
4883
4884         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
4885
4886         isp = (ispsoftc_t *)cam_sim_softc(sim);
4887         mtx_assert(&isp->isp_lock, MA_OWNED);
4888
4889         if (isp->isp_state != ISP_RUNSTATE && ccb->ccb_h.func_code == XPT_SCSI_IO) {
4890                 isp_init(isp);
4891                 if (isp->isp_state != ISP_INITSTATE) {
4892                         /*
4893                          * Lie. Say it was a selection timeout.
4894                          */
4895                         ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
4896                         xpt_freeze_devq(ccb->ccb_h.path, 1);
4897                         xpt_done(ccb);
4898                         return;
4899                 }
4900                 isp->isp_state = ISP_RUNSTATE;
4901         }
4902         isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
4903         ISP_PCMD(ccb) = NULL;
4904
4905         switch (ccb->ccb_h.func_code) {
4906         case XPT_SCSI_IO:       /* Execute the requested I/O operation */
4907                 bus = XS_CHANNEL(ccb);
4908                 /*
4909                  * Do a couple of preliminary checks...
4910                  */
4911                 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
4912                         if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
4913                                 ccb->ccb_h.status = CAM_REQ_INVALID;
4914                                 xpt_done(ccb);
4915                                 break;
4916                         }
4917                 }
4918                 ccb->csio.req_map = NULL;
4919 #ifdef  DIAGNOSTIC
4920                 if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) {
4921                         xpt_print(ccb->ccb_h.path, "invalid target\n");
4922                         ccb->ccb_h.status = CAM_PATH_INVALID;
4923                 } else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) {
4924                         xpt_print(ccb->ccb_h.path, "invalid lun\n");
4925                         ccb->ccb_h.status = CAM_PATH_INVALID;
4926                 }
4927                 if (ccb->ccb_h.status == CAM_PATH_INVALID) {
4928                         xpt_done(ccb);
4929                         break;
4930                 }
4931 #endif
4932                 ccb->csio.scsi_status = SCSI_STATUS_OK;
4933                 if (isp_get_pcmd(isp, ccb)) {
4934                         isp_prt(isp, ISP_LOGWARN, "out of PCMDs");
4935                         cam_freeze_devq(ccb->ccb_h.path);
4936                         cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
4937                         xpt_done(ccb);
4938                         break;
4939                 }
4940                 error = isp_start((XS_T *) ccb);
4941                 switch (error) {
4942                 case CMD_QUEUED:
4943                         ccb->ccb_h.status |= CAM_SIM_QUEUED;
4944                         if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
4945                                 break;
4946                         }
4947                         ts = ccb->ccb_h.timeout;
4948                         if (ts == CAM_TIME_DEFAULT) {
4949                                 ts = 60*1000;
4950                         }
4951                         ts = isp_mstohz(ts);
4952                         callout_reset(&PISP_PCMD(ccb)->wdog, ts, isp_watchdog, ccb);
4953                         break;
4954                 case CMD_RQLATER:
4955                         /*
4956                          * We get this result for FC devices if the loop state isn't ready yet
4957                          * or if the device in question has gone zombie on us.
4958                          *
4959                          * If we've never seen Loop UP at all, we requeue this request and wait
4960                          * for the initial loop up delay to expire.
4961                          */
4962                         lim = ISP_FC_PC(isp, bus)->loop_down_limit;
4963                         if (FCPARAM(isp, bus)->loop_seen_once == 0 || ISP_FC_PC(isp, bus)->loop_down_time >= lim) {
4964                                 if (FCPARAM(isp, bus)->loop_seen_once == 0) {
4965                                         isp_prt(isp, ISP_LOGDEBUG0, "%d.%d loop not seen yet @ %lu", XS_TGT(ccb), XS_LUN(ccb), (unsigned long) time_uptime);
4966                                 } else {
4967                                         isp_prt(isp, ISP_LOGDEBUG0, "%d.%d downtime (%d) > lim (%d)", XS_TGT(ccb), XS_LUN(ccb), ISP_FC_PC(isp, bus)->loop_down_time, lim);
4968                                 }
4969                                 ccb->ccb_h.status = CAM_SEL_TIMEOUT|CAM_DEV_QFRZN;
4970                                 xpt_freeze_devq(ccb->ccb_h.path, 1);
4971                                 isp_free_pcmd(isp, ccb);
4972                                 xpt_done(ccb);
4973                                 break;
4974                         }
4975                         isp_prt(isp, ISP_LOGDEBUG0, "%d.%d retry later", XS_TGT(ccb), XS_LUN(ccb));
4976                         cam_freeze_devq(ccb->ccb_h.path);
4977                         cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
4978                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
4979                         isp_free_pcmd(isp, ccb);
4980                         xpt_done(ccb);
4981                         break;
4982                 case CMD_EAGAIN:
4983                         isp_free_pcmd(isp, ccb);
4984                         cam_freeze_devq(ccb->ccb_h.path);
4985                         cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0);
4986                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
4987                         xpt_done(ccb);
4988                         break;
4989                 case CMD_COMPLETE:
4990                         isp_done((struct ccb_scsiio *) ccb);
4991                         break;
4992                 default:
4993                         isp_prt(isp, ISP_LOGERR, "What's this? 0x%x at %d in file %s", error, __LINE__, __FILE__);
4994                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
4995                         isp_free_pcmd(isp, ccb);
4996                         xpt_done(ccb);
4997                 }
4998                 break;
4999
5000 #ifdef  ISP_TARGET_MODE
5001         case XPT_EN_LUN:                /* Enable/Disable LUN as a target */
5002                 if (ccb->cel.enable) {
5003                         isp_enable_lun(isp, ccb);
5004                 } else {
5005                         isp_disable_lun(isp, ccb);
5006                 }
5007                 break;
5008         case XPT_IMMED_NOTIFY:
5009         case XPT_IMMEDIATE_NOTIFY:      /* Add Immediate Notify Resource */
5010         case XPT_ACCEPT_TARGET_IO:      /* Add Accept Target IO Resource */
5011         {
5012                 tstate_t *tptr = get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
5013                 if (tptr == NULL) {
5014                         tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
5015                 }
5016                 if (tptr == NULL) {
5017                         const char *str;
5018                         uint32_t tag;
5019
5020                         if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
5021                                 str = "XPT_IMMEDIATE_NOTIFY";
5022                                 tag = ccb->cin1.seq_id;
5023                         } else {
5024                                 tag = ccb->atio.tag_id;
5025                                 str = "XPT_ACCEPT_TARGET_IO";
5026                         }
5027                         ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] no state pointer found for %s\n", __func__, tag, str);
5028                         dump_tstates(isp, XS_CHANNEL(ccb));
5029                         ccb->ccb_h.status = CAM_DEV_NOT_THERE;
5030                         break;
5031                 }
5032                 ccb->ccb_h.spriv_field0 = 0;
5033                 ccb->ccb_h.spriv_ptr1 = isp;
5034
5035                 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
5036                         if (ccb->atio.tag_id) {
5037                                 atio_private_data_t *atp = isp_find_atpd(isp, tptr, ccb->atio.tag_id);
5038                                 if (atp) {
5039                                         isp_put_atpd(isp, tptr, atp);
5040                                 }
5041                         }
5042                         tptr->atio_count++;
5043                         SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle);
5044                         ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE ATIO (tag id 0x%x), count now %d\n",
5045                             ccb->atio.tag_id, tptr->atio_count);
5046                         ccb->atio.tag_id = 0;
5047                 } else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
5048                         if (ccb->cin1.tag_id) {
5049                                 inot_private_data_t *ntp = isp_find_ntpd(isp, tptr, ccb->cin1.tag_id, ccb->cin1.seq_id);
5050                                 if (ntp) {
5051                                         isp_put_ntpd(isp, tptr, ntp);
5052                                 }
5053                         }
5054                         tptr->inot_count++;
5055                         SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
5056                         ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
5057                             ccb->cin1.seq_id, tptr->inot_count);
5058                         ccb->cin1.seq_id = 0;
5059                 } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
5060                         tptr->inot_count++;
5061                         SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
5062                         ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
5063                             ccb->cin1.seq_id, tptr->inot_count);
5064                         ccb->cin1.seq_id = 0;
5065                 }
5066                 rls_lun_statep(isp, tptr);
5067                 ccb->ccb_h.status = CAM_REQ_INPROG;
5068                 break;
5069         }
5070         case XPT_NOTIFY_ACK:
5071                 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
5072                 break;
5073         case XPT_NOTIFY_ACKNOWLEDGE:            /* notify ack */
5074         {
5075                 tstate_t *tptr;
5076                 inot_private_data_t *ntp;
5077
5078                 /*
5079                  * XXX: Because we cannot guarantee that the path information in the notify acknowledge ccb
5080                  * XXX: matches that for the immediate notify, we have to *search* for the notify structure
5081                  */
5082                 /*
5083                  * All the relevant path information is in the associated immediate notify
5084                  */
5085                 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);
5086                 ntp = get_ntp_from_tagdata(isp, ccb->cna2.tag_id, ccb->cna2.seq_id, &tptr);
5087                 if (ntp == NULL) {
5088                         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__,
5089                              ccb->cna2.tag_id, ccb->cna2.seq_id);
5090                         ccb->ccb_h.status = CAM_DEV_NOT_THERE;
5091                         xpt_done(ccb);
5092                         break;
5093                 }
5094                 if (isp_handle_platform_target_notify_ack(isp, &ntp->rd.nt)) {
5095                         rls_lun_statep(isp, tptr);
5096                         cam_freeze_devq(ccb->ccb_h.path);
5097                         cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
5098                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
5099                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
5100                         break;
5101                 }
5102                 isp_put_ntpd(isp, tptr, ntp);
5103                 rls_lun_statep(isp, tptr);
5104                 ccb->ccb_h.status = CAM_REQ_CMP;
5105                 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);
5106                 xpt_done(ccb);
5107                 break;
5108         }
5109         case XPT_CONT_TARGET_IO:
5110                 isp_target_start_ctio(isp, ccb, FROM_CAM);
5111                 break;
5112 #endif
5113         case XPT_RESET_DEV:             /* BDR the specified SCSI device */
5114
5115                 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
5116                 tgt = ccb->ccb_h.target_id;
5117                 tgt |= (bus << 16);
5118
5119                 error = isp_control(isp, ISPCTL_RESET_DEV, bus, tgt);
5120                 if (error) {
5121                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
5122                 } else {
5123                         ccb->ccb_h.status = CAM_REQ_CMP;
5124                 }
5125                 xpt_done(ccb);
5126                 break;
5127         case XPT_ABORT:                 /* Abort the specified CCB */
5128         {
5129                 union ccb *accb = ccb->cab.abort_ccb;
5130                 switch (accb->ccb_h.func_code) {
5131 #ifdef  ISP_TARGET_MODE
5132                 case XPT_ACCEPT_TARGET_IO:
5133                         isp_target_mark_aborted(isp, ccb);
5134                         break;
5135 #endif
5136                 case XPT_SCSI_IO:
5137                         error = isp_control(isp, ISPCTL_ABORT_CMD, accb);
5138                         if (error) {
5139                                 ccb->ccb_h.status = CAM_UA_ABORT;
5140                         } else {
5141                                 ccb->ccb_h.status = CAM_REQ_CMP;
5142                         }
5143                         break;
5144                 default:
5145                         ccb->ccb_h.status = CAM_REQ_INVALID;
5146                         break;
5147                 }
5148                 /*
5149                  * This is not a queued CCB, so the caller expects it to be
5150                  * complete when control is returned.
5151                  */
5152                 break;
5153         }
5154 #define IS_CURRENT_SETTINGS(c)  (c->type == CTS_TYPE_CURRENT_SETTINGS)
5155         case XPT_SET_TRAN_SETTINGS:     /* Nexus Settings */
5156                 cts = &ccb->cts;
5157                 if (!IS_CURRENT_SETTINGS(cts)) {
5158                         ccb->ccb_h.status = CAM_REQ_INVALID;
5159                         xpt_done(ccb);
5160                         break;
5161                 }
5162                 tgt = cts->ccb_h.target_id;
5163                 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
5164                 if (IS_SCSI(isp)) {
5165                         struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
5166                         struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
5167                         sdparam *sdp = SDPARAM(isp, bus);
5168                         uint16_t *dptr;
5169
5170                         if (spi->valid == 0 && scsi->valid == 0) {
5171                                 ccb->ccb_h.status = CAM_REQ_CMP;
5172                                 xpt_done(ccb);
5173                                 break;
5174                         }
5175
5176                         /*
5177                          * We always update (internally) from goal_flags
5178                          * so any request to change settings just gets
5179                          * vectored to that location.
5180                          */
5181                         dptr = &sdp->isp_devparam[tgt].goal_flags;
5182
5183                         if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
5184                                 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
5185                                         *dptr |= DPARM_DISC;
5186                                 else
5187                                         *dptr &= ~DPARM_DISC;
5188                         }
5189
5190                         if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
5191                                 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
5192                                         *dptr |= DPARM_TQING;
5193                                 else
5194                                         *dptr &= ~DPARM_TQING;
5195                         }
5196
5197                         if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
5198                                 if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
5199                                         *dptr |= DPARM_WIDE;
5200                                 else
5201                                         *dptr &= ~DPARM_WIDE;
5202                         }
5203
5204                         /*
5205                          * XXX: FIX ME
5206                          */
5207                         if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) && (spi->valid & CTS_SPI_VALID_SYNC_RATE) && (spi->sync_period && spi->sync_offset)) {
5208                                 *dptr |= DPARM_SYNC;
5209                                 /*
5210                                  * XXX: CHECK FOR LEGALITY
5211                                  */
5212                                 sdp->isp_devparam[tgt].goal_period = spi->sync_period;
5213                                 sdp->isp_devparam[tgt].goal_offset = spi->sync_offset;
5214                         } else {
5215                                 *dptr &= ~DPARM_SYNC;
5216                         }
5217                         isp_prt(isp, ISP_LOGDEBUG0, "SET (%d.%d.%jx) to flags %x off %x per %x", bus, tgt, (uintmax_t)cts->ccb_h.target_lun, sdp->isp_devparam[tgt].goal_flags,
5218                             sdp->isp_devparam[tgt].goal_offset, sdp->isp_devparam[tgt].goal_period);
5219                         sdp->isp_devparam[tgt].dev_update = 1;
5220                         sdp->update = 1;
5221                 }
5222                 ccb->ccb_h.status = CAM_REQ_CMP;
5223                 xpt_done(ccb);
5224                 break;
5225         case XPT_GET_TRAN_SETTINGS:
5226                 cts = &ccb->cts;
5227                 tgt = cts->ccb_h.target_id;
5228                 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
5229                 if (IS_FC(isp)) {
5230                         fcparam *fcp = FCPARAM(isp, bus);
5231                         struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
5232                         struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
5233                         unsigned int hdlidx;
5234
5235                         cts->protocol = PROTO_SCSI;
5236                         cts->protocol_version = SCSI_REV_2;
5237                         cts->transport = XPORT_FC;
5238                         cts->transport_version = 0;
5239
5240                         scsi->valid = CTS_SCSI_VALID_TQ;
5241                         scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
5242                         fc->valid = CTS_FC_VALID_SPEED;
5243                         fc->bitrate = 100000;
5244                         fc->bitrate *= fcp->isp_gbspeed;
5245                         hdlidx = fcp->isp_dev_map[tgt] - 1;
5246                         if (hdlidx < MAX_FC_TARG) {
5247                                 fcportdb_t *lp = &fcp->portdb[hdlidx];
5248                                 fc->wwnn = lp->node_wwn;
5249                                 fc->wwpn = lp->port_wwn;
5250                                 fc->port = lp->portid;
5251                                 fc->valid |= CTS_FC_VALID_WWNN | CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT;
5252                         }
5253                 } else {
5254                         struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
5255                         struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
5256                         sdparam *sdp = SDPARAM(isp, bus);
5257                         uint16_t dval, pval, oval;
5258
5259                         if (IS_CURRENT_SETTINGS(cts)) {
5260                                 sdp->isp_devparam[tgt].dev_refresh = 1;
5261                                 sdp->update = 1;
5262                                 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus);
5263                                 dval = sdp->isp_devparam[tgt].actv_flags;
5264                                 oval = sdp->isp_devparam[tgt].actv_offset;
5265                                 pval = sdp->isp_devparam[tgt].actv_period;
5266                         } else {
5267                                 dval = sdp->isp_devparam[tgt].nvrm_flags;
5268                                 oval = sdp->isp_devparam[tgt].nvrm_offset;
5269                                 pval = sdp->isp_devparam[tgt].nvrm_period;
5270                         }
5271
5272                         cts->protocol = PROTO_SCSI;
5273                         cts->protocol_version = SCSI_REV_2;
5274                         cts->transport = XPORT_SPI;
5275                         cts->transport_version = 2;
5276
5277                         spi->valid = 0;
5278                         scsi->valid = 0;
5279                         spi->flags = 0;
5280                         scsi->flags = 0;
5281                         if (dval & DPARM_DISC) {
5282                                 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5283                         }
5284                         if ((dval & DPARM_SYNC) && oval && pval) {
5285                                 spi->sync_offset = oval;
5286                                 spi->sync_period = pval;
5287                         } else {
5288                                 spi->sync_offset = 0;
5289                                 spi->sync_period = 0;
5290                         }
5291                         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5292                         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5293                         spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5294                         if (dval & DPARM_WIDE) {
5295                                 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
5296                         } else {
5297                                 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
5298                         }
5299                         if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
5300                                 scsi->valid = CTS_SCSI_VALID_TQ;
5301                                 if (dval & DPARM_TQING) {
5302                                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5303                                 }
5304                                 spi->valid |= CTS_SPI_VALID_DISC;
5305                         }
5306                         isp_prt(isp, ISP_LOGDEBUG0, "GET %s (%d.%d.%jx) to flags %x off %x per %x", IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
5307                             bus, tgt, (uintmax_t)cts->ccb_h.target_lun, dval, oval, pval);
5308                 }
5309                 ccb->ccb_h.status = CAM_REQ_CMP;
5310                 xpt_done(ccb);
5311                 break;
5312
5313         case XPT_CALC_GEOMETRY:
5314                 cam_calc_geometry(&ccb->ccg, 1);
5315                 xpt_done(ccb);
5316                 break;
5317
5318         case XPT_RESET_BUS:             /* Reset the specified bus */
5319                 bus = cam_sim_bus(sim);
5320                 error = isp_control(isp, ISPCTL_RESET_BUS, bus);
5321                 if (error) {
5322                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
5323                         xpt_done(ccb);
5324                         break;
5325                 }
5326                 if (bootverbose) {
5327                         xpt_print(ccb->ccb_h.path, "reset bus on channel %d\n", bus);
5328                 }
5329                 if (IS_FC(isp)) {
5330                         xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, 0);
5331                 } else {
5332                         xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, 0);
5333                 }
5334                 ccb->ccb_h.status = CAM_REQ_CMP;
5335                 xpt_done(ccb);
5336                 break;
5337
5338         case XPT_TERM_IO:               /* Terminate the I/O process */
5339                 ccb->ccb_h.status = CAM_REQ_INVALID;
5340                 xpt_done(ccb);
5341                 break;
5342
5343         case XPT_SET_SIM_KNOB:          /* Set SIM knobs */
5344         {
5345                 struct ccb_sim_knob *kp = &ccb->knob;
5346                 fcparam *fcp;
5347
5348                 if (!IS_FC(isp)) {
5349                         ccb->ccb_h.status = CAM_REQ_INVALID;
5350                         xpt_done(ccb);
5351                         break;
5352                 }
5353
5354                 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
5355                 fcp = FCPARAM(isp, bus);
5356
5357                 if (kp->xport_specific.fc.valid & KNOB_VALID_ADDRESS) {
5358                         fcp->isp_wwnn = ISP_FC_PC(isp, bus)->def_wwnn = kp->xport_specific.fc.wwnn;
5359                         fcp->isp_wwpn = ISP_FC_PC(isp, bus)->def_wwpn = kp->xport_specific.fc.wwpn;
5360                         isp_prt(isp, ISP_LOGALL, "Setting Channel %d wwns to 0x%jx 0x%jx", bus, fcp->isp_wwnn, fcp->isp_wwpn);
5361                 }
5362                 ccb->ccb_h.status = CAM_REQ_CMP;
5363                 if (kp->xport_specific.fc.valid & KNOB_VALID_ROLE) {
5364                         int rchange = 0;
5365                         int newrole = 0;
5366
5367                         switch (kp->xport_specific.fc.role) {
5368                         case KNOB_ROLE_NONE:
5369                                 if (fcp->role != ISP_ROLE_NONE) {
5370                                         rchange = 1;
5371                                         newrole = ISP_ROLE_NONE;
5372                                 }
5373                                 break;
5374                         case KNOB_ROLE_TARGET:
5375                                 if (fcp->role != ISP_ROLE_TARGET) {
5376                                         rchange = 1;
5377                                         newrole = ISP_ROLE_TARGET;
5378                                 }
5379                                 break;
5380                         case KNOB_ROLE_INITIATOR:
5381                                 if (fcp->role != ISP_ROLE_INITIATOR) {
5382                                         rchange = 1;
5383                                         newrole = ISP_ROLE_INITIATOR;
5384                                 }
5385                                 break;
5386                         case KNOB_ROLE_BOTH:
5387 #if 0
5388                                 if (fcp->role != ISP_ROLE_BOTH) {
5389                                         rchange = 1;
5390                                         newrole = ISP_ROLE_BOTH;
5391                                 }
5392 #else
5393                                 /*
5394                                  * We don't really support dual role at present on FC cards.
5395                                  *
5396                                  * We should, but a bunch of things are currently broken,
5397                                  * so don't allow it.
5398                                  */
5399                                 isp_prt(isp, ISP_LOGERR, "cannot support dual role at present");
5400                                 ccb->ccb_h.status = CAM_REQ_INVALID;
5401 #endif
5402                                 break;
5403                         }
5404                         if (rchange) {
5405                                 ISP_PATH_PRT(isp, ISP_LOGCONFIG, ccb->ccb_h.path, "changing role on from %d to %d\n", fcp->role, newrole);
5406 #ifdef  ISP_TARGET_MODE
5407                                 ISP_SET_PC(isp, bus, tm_enabled, 0);
5408                                 ISP_SET_PC(isp, bus, tm_luns_enabled, 0);
5409 #endif
5410                                 if (isp_fc_change_role(isp, bus, newrole) != 0) {
5411                                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
5412                                         xpt_done(ccb);
5413                                         break;
5414                                 }
5415 #ifdef  ISP_TARGET_MODE
5416                                 if (newrole == ISP_ROLE_TARGET || newrole == ISP_ROLE_BOTH) {
5417                                         /*
5418                                          * Give the new role a chance to complain and settle
5419                                          */
5420                                         msleep(isp, &isp->isp_lock, PRIBIO, "taking a breather", 2);
5421                                         ccb->ccb_h.status = isp_enable_deferred_luns(isp, bus);
5422                                 }
5423 #endif
5424                         }
5425                 }
5426                 xpt_done(ccb);
5427                 break;
5428         }
5429         case XPT_GET_SIM_KNOB:          /* Get SIM knobs */
5430         {
5431                 struct ccb_sim_knob *kp = &ccb->knob;
5432
5433                 if (IS_FC(isp)) {
5434                         fcparam *fcp;
5435
5436                         bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
5437                         fcp = FCPARAM(isp, bus);
5438
5439                         kp->xport_specific.fc.wwnn = fcp->isp_wwnn;
5440                         kp->xport_specific.fc.wwpn = fcp->isp_wwpn;
5441                         switch (fcp->role) {
5442                         case ISP_ROLE_NONE:
5443                                 kp->xport_specific.fc.role = KNOB_ROLE_NONE;
5444                                 break;
5445                         case ISP_ROLE_TARGET:
5446                                 kp->xport_specific.fc.role = KNOB_ROLE_TARGET;
5447                                 break;
5448                         case ISP_ROLE_INITIATOR:
5449                                 kp->xport_specific.fc.role = KNOB_ROLE_INITIATOR;
5450                                 break;
5451                         case ISP_ROLE_BOTH:
5452                                 kp->xport_specific.fc.role = KNOB_ROLE_BOTH;
5453                                 break;
5454                         }
5455                         kp->xport_specific.fc.valid = KNOB_VALID_ADDRESS | KNOB_VALID_ROLE;
5456                         ccb->ccb_h.status = CAM_REQ_CMP;
5457                 } else {
5458                         ccb->ccb_h.status = CAM_REQ_INVALID;
5459                 }
5460                 xpt_done(ccb);
5461                 break;
5462         }
5463         case XPT_PATH_INQ:              /* Path routing inquiry */
5464         {
5465                 struct ccb_pathinq *cpi = &ccb->cpi;
5466
5467                 cpi->version_num = 1;
5468 #ifdef  ISP_TARGET_MODE
5469                 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
5470 #else
5471                 cpi->target_sprt = 0;
5472 #endif
5473                 cpi->hba_eng_cnt = 0;
5474                 cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
5475                 cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
5476                 cpi->bus_id = cam_sim_bus(sim);
5477                 if (isp->isp_osinfo.sixtyfourbit)
5478                         cpi->maxio = (ISP_NSEG64_MAX - 1) * PAGE_SIZE;
5479                 else
5480                         cpi->maxio = (ISP_NSEG_MAX - 1) * PAGE_SIZE;
5481
5482                 bus = cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
5483                 if (IS_FC(isp)) {
5484                         fcparam *fcp = FCPARAM(isp, bus);
5485
5486                         cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED;
5487
5488                         /*
5489                          * Because our loop ID can shift from time to time,
5490                          * make our initiator ID out of range of our bus.
5491                          */
5492                         cpi->initiator_id = cpi->max_target + 1;
5493
5494                         /*
5495                          * Set base transfer capabilities for Fibre Channel, for this HBA.
5496                          */
5497                         if (IS_25XX(isp)) {
5498                                 cpi->base_transfer_speed = 8000000;
5499                         } else if (IS_24XX(isp)) {
5500                                 cpi->base_transfer_speed = 4000000;
5501                         } else if (IS_23XX(isp)) {
5502                                 cpi->base_transfer_speed = 2000000;
5503                         } else {
5504                                 cpi->base_transfer_speed = 1000000;
5505                         }
5506                         cpi->hba_inquiry = PI_TAG_ABLE;
5507                         cpi->transport = XPORT_FC;
5508                         cpi->transport_version = 0;
5509                         cpi->xport_specific.fc.wwnn = fcp->isp_wwnn;
5510                         cpi->xport_specific.fc.wwpn = fcp->isp_wwpn;
5511                         cpi->xport_specific.fc.port = fcp->isp_portid;
5512                         cpi->xport_specific.fc.bitrate = fcp->isp_gbspeed * 1000;
5513                 } else {
5514                         sdparam *sdp = SDPARAM(isp, bus);
5515                         cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
5516                         cpi->hba_misc = PIM_UNMAPPED;
5517                         cpi->initiator_id = sdp->isp_initiator_id;
5518                         cpi->base_transfer_speed = 3300;
5519                         cpi->transport = XPORT_SPI;
5520                         cpi->transport_version = 2;
5521                 }
5522                 cpi->protocol = PROTO_SCSI;
5523                 cpi->protocol_version = SCSI_REV_2;
5524                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
5525                 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
5526                 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
5527                 cpi->unit_number = cam_sim_unit(sim);
5528                 cpi->ccb_h.status = CAM_REQ_CMP;
5529                 xpt_done(ccb);
5530                 break;
5531         }
5532         default:
5533                 ccb->ccb_h.status = CAM_REQ_INVALID;
5534                 xpt_done(ccb);
5535                 break;
5536         }
5537 }
5538
5539 #define ISPDDB  (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
5540
5541 void
5542 isp_done(XS_T *sccb)
5543 {
5544         ispsoftc_t *isp = XS_ISP(sccb);
5545         uint32_t status;
5546
5547         if (XS_NOERR(sccb))
5548                 XS_SETERR(sccb, CAM_REQ_CMP);
5549
5550         if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && (sccb->scsi_status != SCSI_STATUS_OK)) {
5551                 sccb->ccb_h.status &= ~CAM_STATUS_MASK;
5552                 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
5553                         sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
5554                 } else {
5555                         sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
5556                 }
5557         }
5558
5559         sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
5560         status = sccb->ccb_h.status & CAM_STATUS_MASK;
5561         if (status != CAM_REQ_CMP) {
5562                 if (status != CAM_SEL_TIMEOUT)
5563                         isp_prt(isp, ISP_LOGDEBUG0, "target %d lun %d CAM status 0x%x SCSI status 0x%x", XS_TGT(sccb), XS_LUN(sccb), sccb->ccb_h.status, sccb->scsi_status);
5564                 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
5565                         sccb->ccb_h.status |= CAM_DEV_QFRZN;
5566                         xpt_freeze_devq(sccb->ccb_h.path, 1);
5567                 }
5568         }
5569
5570         if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) && (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5571                 xpt_print(sccb->ccb_h.path, "cam completion status 0x%x\n", sccb->ccb_h.status);
5572         }
5573
5574         if (callout_active(&PISP_PCMD(sccb)->wdog))
5575                 callout_stop(&PISP_PCMD(sccb)->wdog);
5576         isp_free_pcmd(isp, (union ccb *) sccb);
5577         xpt_done((union ccb *) sccb);
5578 }
5579
5580 void
5581 isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
5582 {
5583         int bus;
5584         static const char prom0[] = "Chan %d PortID 0x%06x handle 0x%x %s %s WWPN 0x%08x%08x";
5585         static const char prom2[] = "Chan %d PortID 0x%06x handle 0x%x %s %s tgt %u WWPN 0x%08x%08x";
5586         char buf[64];
5587         char *msg = NULL;
5588         target_id_t tgt;
5589         fcportdb_t *lp;
5590         struct isp_fc *fc;
5591         struct cam_path *tmppath;
5592         va_list ap;
5593
5594         switch (cmd) {
5595         case ISPASYNC_NEW_TGT_PARAMS:
5596         {
5597                 struct ccb_trans_settings_scsi *scsi;
5598                 struct ccb_trans_settings_spi *spi;
5599                 int flags, tgt;
5600                 sdparam *sdp;
5601                 struct ccb_trans_settings cts;
5602
5603                 memset(&cts, 0, sizeof (struct ccb_trans_settings));
5604
5605                 va_start(ap, cmd);
5606                 bus = va_arg(ap, int);
5607                 tgt = va_arg(ap, int);
5608                 va_end(ap);
5609                 sdp = SDPARAM(isp, bus);
5610
5611                 if (xpt_create_path(&tmppath, NULL, cam_sim_path(ISP_SPI_PC(isp, bus)->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
5612                         isp_prt(isp, ISP_LOGWARN, "isp_async cannot make temp path for %d.%d", tgt, bus);
5613                         break;
5614                 }
5615                 flags = sdp->isp_devparam[tgt].actv_flags;
5616                 cts.type = CTS_TYPE_CURRENT_SETTINGS;
5617                 cts.protocol = PROTO_SCSI;
5618                 cts.transport = XPORT_SPI;
5619
5620                 scsi = &cts.proto_specific.scsi;
5621                 spi = &cts.xport_specific.spi;
5622
5623                 if (flags & DPARM_TQING) {
5624                         scsi->valid |= CTS_SCSI_VALID_TQ;
5625                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5626                 }
5627
5628                 if (flags & DPARM_DISC) {
5629                         spi->valid |= CTS_SPI_VALID_DISC;
5630                         spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5631                 }
5632                 spi->flags |= CTS_SPI_VALID_BUS_WIDTH;
5633                 if (flags & DPARM_WIDE) {
5634                         spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
5635                 } else {
5636                         spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
5637                 }
5638                 if (flags & DPARM_SYNC) {
5639                         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5640                         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5641                         spi->sync_period = sdp->isp_devparam[tgt].actv_period;
5642                         spi->sync_offset = sdp->isp_devparam[tgt].actv_offset;
5643                 }
5644                 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);
5645                 xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
5646                 xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
5647                 xpt_free_path(tmppath);
5648                 break;
5649         }
5650         case ISPASYNC_BUS_RESET:
5651         {
5652                 va_start(ap, cmd);
5653                 bus = va_arg(ap, int);
5654                 va_end(ap);
5655                 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected", bus);
5656                 if (IS_FC(isp)) {
5657                         xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, NULL);
5658                 } else {
5659                         xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, NULL);
5660                 }
5661                 break;
5662         }
5663         case ISPASYNC_LIP:
5664                 if (msg == NULL) {
5665                         msg = "LIP Received";
5666                 }
5667                 /* FALLTHROUGH */
5668         case ISPASYNC_LOOP_RESET:
5669                 if (msg == NULL) {
5670                         msg = "LOOP Reset";
5671                 }
5672                 /* FALLTHROUGH */
5673         case ISPASYNC_LOOP_DOWN:
5674         {
5675                 if (msg == NULL) {
5676                         msg = "LOOP Down";
5677                 }
5678                 va_start(ap, cmd);
5679                 bus = va_arg(ap, int);
5680                 va_end(ap);
5681
5682                 FCPARAM(isp, bus)->link_active = 0;
5683
5684                 fc = ISP_FC_PC(isp, bus);
5685                 if (cmd == ISPASYNC_LOOP_DOWN && fc->ready) {
5686                         /*
5687                          * We don't do any simq freezing if we are only in target mode
5688                          */
5689                         if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
5690                                 if (fc->path) {
5691                                         isp_freeze_loopdown(isp, bus, msg);
5692                                 }
5693                                 if (!callout_active(&fc->ldt)) {
5694                                         callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc);
5695                                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Loop Down Timer @ %lu", (unsigned long) time_uptime);
5696                                 }
5697                         }
5698                 }
5699                 isp_fcp_reset_crn(fc, /*tgt*/0, /*tgt_set*/ 0);
5700
5701                 isp_prt(isp, ISP_LOGINFO, "Chan %d: %s", bus, msg);
5702                 break;
5703         }
5704         case ISPASYNC_LOOP_UP:
5705                 va_start(ap, cmd);
5706                 bus = va_arg(ap, int);
5707                 va_end(ap);
5708                 fc = ISP_FC_PC(isp, bus);
5709                 /*
5710                  * Now we just note that Loop has come up. We don't
5711                  * actually do anything because we're waiting for a
5712                  * Change Notify before activating the FC cleanup
5713                  * thread to look at the state of the loop again.
5714                  */
5715                 FCPARAM(isp, bus)->link_active = 1;
5716                 fc->loop_dead = 0;
5717                 fc->loop_down_time = 0;
5718                 isp_prt(isp, ISP_LOGINFO, "Chan %d Loop UP", bus);
5719                 break;
5720         case ISPASYNC_DEV_ARRIVED:
5721                 va_start(ap, cmd);
5722                 bus = va_arg(ap, int);
5723                 lp = va_arg(ap, fcportdb_t *);
5724                 va_end(ap);
5725                 fc = ISP_FC_PC(isp, bus);
5726                 lp->announced = 0;
5727                 lp->gone_timer = 0;
5728                 if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) && (lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) {
5729                         int dbidx = lp - FCPARAM(isp, bus)->portdb;
5730                         int i;
5731
5732                         for (i = 0; i < MAX_FC_TARG; i++) {
5733                                 if (i >= FL_ID && i <= SNS_ID) {
5734                                         continue;
5735                                 }
5736                                 if (FCPARAM(isp, bus)->isp_dev_map[i] == 0) {
5737                                         break;
5738                                 }
5739                         }
5740                         if (i < MAX_FC_TARG) {
5741                                 FCPARAM(isp, bus)->isp_dev_map[i] = dbidx + 1;
5742                                 lp->dev_map_idx = i + 1;
5743                         } else {
5744                                 isp_prt(isp, ISP_LOGWARN, "out of target ids");
5745                                 isp_dump_portdb(isp, bus);
5746                         }
5747                 }
5748                 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5749                 if (lp->dev_map_idx) {
5750                         tgt = lp->dev_map_idx - 1;
5751                         isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "arrived at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5752                         isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
5753                         isp_make_here(isp, bus, tgt);
5754                 } else {
5755                         isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "arrived", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5756                 }
5757                 break;
5758         case ISPASYNC_DEV_CHANGED:
5759                 va_start(ap, cmd);
5760                 bus = va_arg(ap, int);
5761                 lp = va_arg(ap, fcportdb_t *);
5762                 va_end(ap);
5763                 fc = ISP_FC_PC(isp, bus);
5764                 lp->announced = 0;
5765                 lp->gone_timer = 0;
5766                 if (isp_change_is_bad) {
5767                         lp->state = FC_PORTDB_STATE_NIL;
5768                         if (lp->dev_map_idx) {
5769                                 tgt = lp->dev_map_idx - 1;
5770                                 FCPARAM(isp, bus)->isp_dev_map[tgt] = 0;
5771                                 lp->dev_map_idx = 0;
5772                                 isp_prt(isp, ISP_LOGCONFIG, prom3, bus, lp->portid, tgt, "change is bad");
5773                                 isp_make_gone(isp, bus, tgt);
5774                         } else {
5775                                 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5776                                 isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "changed and departed",
5777                                     (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5778                         }
5779                 } else {
5780                         lp->portid = lp->new_portid;
5781                         lp->prli_word3 = lp->new_prli_word3;
5782                         isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5783                         if (lp->dev_map_idx) {
5784                                 int t = lp->dev_map_idx - 1;
5785                                 FCPARAM(isp, bus)->isp_dev_map[t] = (lp - FCPARAM(isp, bus)->portdb) + 1;
5786                                 tgt = lp->dev_map_idx - 1;
5787                                 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "changed at", tgt,
5788                                     (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5789                                 isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
5790                         } else {
5791                                 isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "changed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5792                         }
5793                 }
5794                 break;
5795         case ISPASYNC_DEV_STAYED:
5796                 va_start(ap, cmd);
5797                 bus = va_arg(ap, int);
5798                 lp = va_arg(ap, fcportdb_t *);
5799                 va_end(ap);
5800                 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5801                 if (lp->dev_map_idx) {
5802                         fc = ISP_FC_PC(isp, bus);
5803                         tgt = lp->dev_map_idx - 1;
5804                         isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "stayed at", tgt,
5805                             (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5806                 } else {
5807                         isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "stayed",
5808                             (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5809                 }
5810                 break;
5811         case ISPASYNC_DEV_GONE:
5812                 va_start(ap, cmd);
5813                 bus = va_arg(ap, int);
5814                 lp = va_arg(ap, fcportdb_t *);
5815                 va_end(ap);
5816                 fc = ISP_FC_PC(isp, bus);
5817                 /*
5818                  * If this has a virtual target and we haven't marked it
5819                  * that we're going to have isp_gdt tell the OS it's gone,
5820                  * set the isp_gdt timer running on it.
5821                  *
5822                  * If it isn't marked that isp_gdt is going to get rid of it,
5823                  * announce that it's gone.
5824                  *
5825                  */
5826                 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5827                 if (lp->dev_map_idx && lp->announced == 0) {
5828                         lp->announced = 1;
5829                         lp->state = FC_PORTDB_STATE_ZOMBIE;
5830                         lp->gone_timer = ISP_FC_PC(isp, bus)->gone_device_time;
5831                         if (fc->ready && !callout_active(&fc->gdt)) {
5832                                 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);
5833                                 callout_reset(&fc->gdt, hz, isp_gdt, fc);
5834                         }
5835                         tgt = lp->dev_map_idx - 1;
5836                         isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "gone zombie at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5837                         isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
5838                 } else if (lp->announced == 0) {
5839                         isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "departed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5840                 }
5841                 break;
5842         case ISPASYNC_CHANGE_NOTIFY:
5843         {
5844                 char *msg;
5845                 int evt, nphdl, nlstate, reason;
5846
5847                 va_start(ap, cmd);
5848                 bus = va_arg(ap, int);
5849                 evt = va_arg(ap, int);
5850                 if (IS_24XX(isp) && evt == ISPASYNC_CHANGE_PDB) {
5851                         nphdl = va_arg(ap, int);
5852                         nlstate = va_arg(ap, int);
5853                         reason = va_arg(ap, int);
5854                 } else {
5855                         nphdl = NIL_HANDLE;
5856                         nlstate = reason = 0;
5857                 }
5858                 va_end(ap);
5859                 fc = ISP_FC_PC(isp, bus);
5860
5861                 if (evt == ISPASYNC_CHANGE_PDB) {
5862                         msg = "Chan %d Port Database Changed";
5863                 } else if (evt == ISPASYNC_CHANGE_SNS) {
5864                         msg = "Chan %d Name Server Database Changed";
5865                 } else {
5866                         msg = "Chan %d Other Change Notify";
5867                 }
5868
5869                 /*
5870                  * If the loop down timer is running, cancel it.
5871                  */
5872                 if (fc->ready && callout_active(&fc->ldt)) {
5873                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Stopping Loop Down Timer @ %lu", (unsigned long) time_uptime);
5874                         callout_stop(&fc->ldt);
5875                 }
5876                 isp_prt(isp, ISP_LOGINFO, msg, bus);
5877                 if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
5878                         isp_freeze_loopdown(isp, bus, msg);
5879                 }
5880                 wakeup(fc);
5881                 break;
5882         }
5883 #ifdef  ISP_TARGET_MODE
5884         case ISPASYNC_TARGET_NOTIFY:
5885         {
5886                 isp_notify_t *notify;
5887                 va_start(ap, cmd);
5888                 notify = va_arg(ap, isp_notify_t *);
5889                 va_end(ap);
5890                 switch (notify->nt_ncode) {
5891                 case NT_ABORT_TASK:
5892                 case NT_ABORT_TASK_SET:
5893                 case NT_CLEAR_ACA:
5894                 case NT_CLEAR_TASK_SET:
5895                 case NT_LUN_RESET:
5896                 case NT_TARGET_RESET:
5897                         /*
5898                          * These are task management functions.
5899                          */
5900                         isp_handle_platform_target_tmf(isp, notify);
5901                         break;
5902                 case NT_BUS_RESET:
5903                 case NT_LIP_RESET:
5904                 case NT_LINK_UP:
5905                 case NT_LINK_DOWN:
5906                         /*
5907                          * No action need be taken here.
5908                          */
5909                         break;
5910                 case NT_HBA_RESET:
5911                         isp_del_all_wwn_entries(isp, ISP_NOCHAN);
5912                         break;
5913                 case NT_GLOBAL_LOGOUT:
5914                 case NT_LOGOUT:
5915                         /*
5916                          * This is device arrival/departure notification
5917                          */
5918                         isp_handle_platform_target_notify_ack(isp, notify);
5919                         break;
5920                 case NT_ARRIVED:
5921                 {
5922                         struct ac_contract ac;
5923                         struct ac_device_changed *fc;
5924
5925                         ac.contract_number = AC_CONTRACT_DEV_CHG;
5926                         fc = (struct ac_device_changed *) ac.contract_data;
5927                         fc->wwpn = notify->nt_wwn;
5928                         fc->port = notify->nt_sid;
5929                         fc->target = notify->nt_nphdl;
5930                         fc->arrived = 1;
5931                         xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac);
5932                         break;
5933                 }
5934                 case NT_DEPARTED:
5935                 {
5936                         struct ac_contract ac;
5937                         struct ac_device_changed *fc;
5938
5939                         ac.contract_number = AC_CONTRACT_DEV_CHG;
5940                         fc = (struct ac_device_changed *) ac.contract_data;
5941                         fc->wwpn = notify->nt_wwn;
5942                         fc->port = notify->nt_sid;
5943                         fc->target = notify->nt_nphdl;
5944                         fc->arrived = 0;
5945                         xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac);
5946                         break;
5947                 }
5948                 default:
5949                         isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode);
5950                         isp_handle_platform_target_notify_ack(isp, notify);
5951                         break;
5952                 }
5953                 break;
5954         }
5955         case ISPASYNC_TARGET_NOTIFY_ACK:
5956         {
5957                 void *inot;
5958                 va_start(ap, cmd);
5959                 inot = va_arg(ap, void *);
5960                 va_end(ap);
5961                 if (isp_notify_ack(isp, inot)) {
5962                         isp_tna_t *tp = malloc(sizeof (*tp), M_DEVBUF, M_NOWAIT);
5963                         if (tp) {
5964                                 tp->isp = isp;
5965                                 if (inot) {
5966                                         memcpy(tp->data, inot, sizeof (tp->data));
5967                                         tp->not = tp->data;
5968                                 } else {
5969                                         tp->not = NULL;
5970                                 }
5971                                 callout_init_mtx(&tp->timer, &isp->isp_lock, 0);
5972                                 callout_reset(&tp->timer, 5,
5973                                     isp_refire_notify_ack, tp);
5974                         } else {
5975                                 isp_prt(isp, ISP_LOGERR, "you lose- cannot allocate a notify refire");
5976                         }
5977                 }
5978                 break;
5979         }
5980         case ISPASYNC_TARGET_ACTION:
5981         {
5982                 isphdr_t *hp;
5983
5984                 va_start(ap, cmd);
5985                 hp = va_arg(ap, isphdr_t *);
5986                 va_end(ap);
5987                 switch (hp->rqs_entry_type) {
5988                 default:
5989                         isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x", __func__, hp->rqs_entry_type);
5990                         break;
5991                 case RQSTYPE_NOTIFY:
5992                         if (IS_SCSI(isp)) {
5993                                 isp_handle_platform_notify_scsi(isp, (in_entry_t *) hp);
5994                         } else if (IS_24XX(isp)) {
5995                                 isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp);
5996                         } else {
5997                                 isp_handle_platform_notify_fc(isp, (in_fcentry_t *) hp);
5998                         }
5999                         break;
6000                 case RQSTYPE_ATIO:
6001                         if (IS_24XX(isp)) {
6002                                 isp_handle_platform_atio7(isp, (at7_entry_t *) hp);
6003                         } else {
6004                                 isp_handle_platform_atio(isp, (at_entry_t *) hp);
6005                         }
6006                         break;
6007                 case RQSTYPE_ATIO2:
6008                         isp_handle_platform_atio2(isp, (at2_entry_t *) hp);
6009                         break;
6010                 case RQSTYPE_CTIO7:
6011                 case RQSTYPE_CTIO3:
6012                 case RQSTYPE_CTIO2:
6013                 case RQSTYPE_CTIO:
6014                         isp_handle_platform_ctio(isp, hp);
6015                         break;
6016                 case RQSTYPE_ABTS_RCVD:
6017                 {
6018                         abts_t *abts = (abts_t *)hp;
6019                         isp_notify_t notify, *nt = &notify;
6020                         tstate_t *tptr;
6021                         fcportdb_t *lp;
6022                         uint16_t chan;
6023                         uint32_t sid, did;
6024
6025                         did = (abts->abts_did_hi << 16) | abts->abts_did_lo;
6026                         sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo;
6027                         ISP_MEMZERO(nt, sizeof (isp_notify_t));
6028
6029                         nt->nt_hba = isp;
6030                         nt->nt_did = did;
6031                         nt->nt_nphdl = abts->abts_nphdl;
6032                         nt->nt_sid = sid;
6033                         isp_find_chan_by_did(isp, did, &chan);
6034                         if (chan == ISP_NOCHAN) {
6035                                 nt->nt_tgt = TGT_ANY;
6036                         } else {
6037                                 nt->nt_tgt = FCPARAM(isp, chan)->isp_wwpn;
6038                                 if (isp_find_pdb_by_loopid(isp, chan, abts->abts_nphdl, &lp)) {
6039                                         nt->nt_wwn = lp->port_wwn;
6040                                 } else {
6041                                         nt->nt_wwn = INI_ANY;
6042                                 }
6043                         }
6044                         /*
6045                          * Try hard to find the lun for this command.
6046                          */
6047                         tptr = get_lun_statep_from_tag(isp, chan, abts->abts_rxid_task);
6048                         if (tptr) {
6049                                 nt->nt_lun = tptr->ts_lun;
6050                                 rls_lun_statep(isp, tptr);
6051                         } else {
6052                                 nt->nt_lun = LUN_ANY;
6053                         }
6054                         nt->nt_need_ack = 1;
6055                         nt->nt_tagval = abts->abts_rxid_task;
6056                         nt->nt_tagval |= (((uint64_t) abts->abts_rxid_abts) << 32);
6057                         if (abts->abts_rxid_task == ISP24XX_NO_TASK) {
6058                                 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)",
6059                                     abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rx_id, abts->abts_ox_id);
6060                         } else {
6061                                 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)",
6062                                     abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rxid_task, abts->abts_rx_id, abts->abts_ox_id);
6063                         }
6064                         nt->nt_channel = chan;
6065                         nt->nt_ncode = NT_ABORT_TASK;
6066                         nt->nt_lreserved = hp;
6067                         isp_handle_platform_target_tmf(isp, nt);
6068                         break;
6069                 }
6070                 case RQSTYPE_ENABLE_LUN:
6071                 case RQSTYPE_MODIFY_LUN:
6072                         isp_ledone(isp, (lun_entry_t *) hp);
6073                         break;
6074                 }
6075                 break;
6076         }
6077 #endif
6078         case ISPASYNC_FW_CRASH:
6079         {
6080                 uint16_t mbox1, mbox6;
6081                 mbox1 = ISP_READ(isp, OUTMAILBOX1);
6082                 if (IS_DUALBUS(isp)) { 
6083                         mbox6 = ISP_READ(isp, OUTMAILBOX6);
6084                 } else {
6085                         mbox6 = 0;
6086                 }
6087                 isp_prt(isp, ISP_LOGERR, "Internal Firmware Error on bus %d @ RISC Address 0x%x", mbox6, mbox1);
6088                 mbox1 = isp->isp_osinfo.mbox_sleep_ok;
6089                 isp->isp_osinfo.mbox_sleep_ok = 0;
6090                 isp_reinit(isp, 1);
6091                 isp->isp_osinfo.mbox_sleep_ok = mbox1;
6092                 isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
6093                 break;
6094         }
6095         default:
6096                 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
6097                 break;
6098         }
6099 }
6100
6101
6102 /*
6103  * Locks are held before coming here.
6104  */
6105 void
6106 isp_uninit(ispsoftc_t *isp)
6107 {
6108         if (IS_24XX(isp)) {
6109                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
6110         } else {
6111                 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
6112         }
6113         ISP_DISABLE_INTS(isp);
6114 }
6115
6116 /*
6117  * When we want to get the 'default' WWNs (when lacking NVRAM), we pick them
6118  * up from our platform default (defww{p|n}n) and morph them based upon
6119  * channel.
6120  * 
6121  * When we want to get the 'active' WWNs, we get NVRAM WWNs and then morph them
6122  * based upon channel.
6123  */
6124
6125 uint64_t
6126 isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn)
6127 {
6128         uint64_t seed;
6129         struct isp_fc *fc = ISP_FC_PC(isp, chan);
6130
6131         /*
6132          * If we're asking for a active WWN, the default overrides get
6133          * returned, otherwise the NVRAM value is picked.
6134          * 
6135          * If we're asking for a default WWN, we just pick the default override.
6136          */
6137         if (isactive) {
6138                 seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
6139                 if (seed) {
6140                         return (seed);
6141                 }
6142                 seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram : FCPARAM(isp, chan)->isp_wwpn_nvram;
6143                 if (seed) {
6144                         return (seed);
6145                 }
6146                 return (0x400000007F000009ull);
6147         }
6148
6149         seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
6150
6151         /*
6152          * For channel zero just return what we have. For either ACTIVE or
6153          * DEFAULT cases, we depend on default override of NVRAM values for
6154          * channel zero.
6155          */
6156         if (chan == 0) {
6157                 return (seed);
6158         }
6159
6160         /*
6161          * For other channels, we are doing one of three things:
6162          * 
6163          * 1. If what we have now is non-zero, return it. Otherwise we morph
6164          * values from channel 0. 2. If we're here for a WWPN we synthesize
6165          * it if Channel 0's wwpn has a type 2 NAA. 3. If we're here for a
6166          * WWNN we synthesize it if Channel 0's wwnn has a type 2 NAA.
6167          */
6168
6169         if (seed) {
6170                 return (seed);
6171         }
6172         seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn : ISP_FC_PC(isp, 0)->def_wwpn;
6173         if (seed == 0)
6174                 seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram : FCPARAM(isp, 0)->isp_wwpn_nvram;
6175
6176         if (((seed >> 60) & 0xf) == 2) {
6177                 /*
6178                  * The type 2 NAA fields for QLogic cards appear be laid out
6179                  * thusly:
6180                  * 
6181                  * bits 63..60 NAA == 2 bits 59..57 unused/zero bit 56
6182                  * port (1) or node (0) WWN distinguishor bit 48
6183                  * physical port on dual-port chips (23XX/24XX)
6184                  * 
6185                  * This is somewhat nutty, particularly since bit 48 is
6186                  * irrelevant as they assign separate serial numbers to
6187                  * different physical ports anyway.
6188                  * 
6189                  * We'll stick our channel number plus one first into bits
6190                  * 57..59 and thence into bits 52..55 which allows for 8 bits
6191                  * of channel which is comfortably more than our maximum
6192                  * (126) now.
6193                  */
6194                 seed &= ~0x0FF0000000000000ULL;
6195                 if (iswwnn == 0) {
6196                         seed |= ((uint64_t) (chan + 1) & 0xf) << 56;
6197                         seed |= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52;
6198                 }
6199         } else {
6200                 seed = 0;
6201         }
6202         return (seed);
6203 }
6204
6205 void
6206 isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
6207 {
6208         int loc;
6209         char lbuf[200];
6210         va_list ap;
6211
6212         if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
6213                 return;
6214         }
6215         snprintf(lbuf, sizeof (lbuf), "%s: ", device_get_nameunit(isp->isp_dev));
6216         loc = strlen(lbuf);
6217         va_start(ap, fmt);
6218         vsnprintf(&lbuf[loc], sizeof (lbuf) - loc - 1, fmt, ap); 
6219         va_end(ap);
6220         printf("%s\n", lbuf);
6221 }
6222
6223 void
6224 isp_xs_prt(ispsoftc_t *isp, XS_T *xs, int level, const char *fmt, ...)
6225 {
6226         va_list ap;
6227         if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
6228                 return;
6229         }
6230         xpt_print_path(xs->ccb_h.path);
6231         va_start(ap, fmt);
6232         vprintf(fmt, ap);
6233         va_end(ap);
6234         printf("\n");
6235 }
6236
6237 uint64_t
6238 isp_nanotime_sub(struct timespec *b, struct timespec *a)
6239 {
6240         uint64_t elapsed;
6241         struct timespec x = *b;
6242         timespecsub(&x, a);
6243         elapsed = GET_NANOSEC(&x);
6244         if (elapsed == 0)
6245                 elapsed++;
6246         return (elapsed);
6247 }
6248
6249 int
6250 isp_mbox_acquire(ispsoftc_t *isp)
6251 {
6252         if (isp->isp_osinfo.mboxbsy) {
6253                 return (1);
6254         } else {
6255                 isp->isp_osinfo.mboxcmd_done = 0;
6256                 isp->isp_osinfo.mboxbsy = 1;
6257                 return (0);
6258         }
6259 }
6260
6261 void
6262 isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
6263 {
6264         unsigned int usecs = mbp->timeout;
6265         unsigned int max, olim, ilim;
6266
6267         if (usecs == 0) {
6268                 usecs = MBCMD_DEFAULT_TIMEOUT;
6269         }
6270         max = isp->isp_mbxwrk0 + 1;
6271
6272         if (isp->isp_osinfo.mbox_sleep_ok) {
6273                 unsigned int ms = (usecs + 999) / 1000;
6274
6275                 isp->isp_osinfo.mbox_sleep_ok = 0;
6276                 isp->isp_osinfo.mbox_sleeping = 1;
6277                 for (olim = 0; olim < max; olim++) {
6278                         msleep(&isp->isp_mbxworkp, &isp->isp_osinfo.lock, PRIBIO, "ispmbx_sleep", isp_mstohz(ms));
6279                         if (isp->isp_osinfo.mboxcmd_done) {
6280                                 break;
6281                         }
6282                 }
6283                 isp->isp_osinfo.mbox_sleep_ok = 1;
6284                 isp->isp_osinfo.mbox_sleeping = 0;
6285         } else {
6286                 for (olim = 0; olim < max; olim++) {
6287                         for (ilim = 0; ilim < usecs; ilim += 100) {
6288                                 uint32_t isr;
6289                                 uint16_t sema, mbox;
6290                                 if (isp->isp_osinfo.mboxcmd_done) {
6291                                         break;
6292                                 }
6293                                 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
6294                                         isp_intr(isp, isr, sema, mbox);
6295                                         if (isp->isp_osinfo.mboxcmd_done) {
6296                                                 break;
6297                                         }
6298                                 }
6299                                 ISP_DELAY(100);
6300                         }
6301                         if (isp->isp_osinfo.mboxcmd_done) {
6302                                 break;
6303                         }
6304                 }
6305         }
6306         if (isp->isp_osinfo.mboxcmd_done == 0) {
6307                 isp_prt(isp, ISP_LOGWARN, "%s Mailbox Command (0x%x) Timeout (%uus) (started @ %s:%d)",
6308                     isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled", isp->isp_lastmbxcmd, usecs, mbp->func, mbp->lineno);
6309                 mbp->param[0] = MBOX_TIMEOUT;
6310                 isp->isp_osinfo.mboxcmd_done = 1;
6311         }
6312 }
6313
6314 void
6315 isp_mbox_notify_done(ispsoftc_t *isp)
6316 {
6317         if (isp->isp_osinfo.mbox_sleeping) {
6318                 wakeup(&isp->isp_mbxworkp);
6319         }
6320         isp->isp_osinfo.mboxcmd_done = 1;
6321 }
6322
6323 void
6324 isp_mbox_release(ispsoftc_t *isp)
6325 {
6326         isp->isp_osinfo.mboxbsy = 0;
6327 }
6328
6329 int
6330 isp_fc_scratch_acquire(ispsoftc_t *isp, int chan)
6331 {
6332         int ret = 0;
6333         if (isp->isp_osinfo.pc.fc[chan].fcbsy) {
6334                 ret = -1;
6335         } else {
6336                 isp->isp_osinfo.pc.fc[chan].fcbsy = 1;
6337         }
6338         return (ret);
6339 }
6340
6341 int
6342 isp_mstohz(int ms)
6343 {
6344         int hz;
6345         struct timeval t;
6346         t.tv_sec = ms / 1000;
6347         t.tv_usec = (ms % 1000) * 1000;
6348         hz = tvtohz(&t);
6349         if (hz < 0) {
6350                 hz = 0x7fffffff;
6351         }
6352         if (hz == 0) {
6353                 hz = 1;
6354         }
6355         return (hz);
6356 }
6357
6358 void
6359 isp_platform_intr(void *arg)
6360 {
6361         ispsoftc_t *isp = arg;
6362         uint32_t isr;
6363         uint16_t sema, mbox;
6364
6365         ISP_LOCK(isp);
6366         isp->isp_intcnt++;
6367         if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
6368                 isp->isp_intbogus++;
6369         } else {
6370                 isp_intr(isp, isr, sema, mbox);
6371         }
6372         ISP_UNLOCK(isp);
6373 }
6374
6375 void
6376 isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl)
6377 {
6378         if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
6379                 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTREAD);
6380         } else {
6381                 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTWRITE);
6382         }
6383         bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap);
6384 }
6385
6386 /*
6387  * Reset the command reference number for all LUNs on a specific target
6388  * (needed when a target arrives again) or for all targets on a port
6389  * (needed for events like a LIP).
6390  */
6391 void
6392 isp_fcp_reset_crn(struct isp_fc *fc, uint32_t tgt, int tgt_set)
6393 {
6394         int i;
6395         struct isp_nexus *nxp;
6396
6397         if (tgt_set == 0)
6398                 isp_prt(fc->isp, ISP_LOG_SANCFG, "resetting CRN on all targets");
6399         else
6400                 isp_prt(fc->isp, ISP_LOG_SANCFG, "resetting CRN target %u", tgt);
6401
6402         for (i = 0; i < NEXUS_HASH_WIDTH; i++) {
6403                 nxp = fc->nexus_hash[i];
6404                 while (nxp) {
6405                         if ((tgt_set != 0) && (tgt == nxp->tgt))
6406                                 nxp->crnseed = 0;
6407
6408                         nxp = nxp->next;
6409                 }
6410         }
6411 }
6412
6413 int
6414 isp_fcp_next_crn(ispsoftc_t *isp, uint8_t *crnp, XS_T *cmd)
6415 {
6416         uint32_t chan, tgt, lun;
6417         struct isp_fc *fc;
6418         struct isp_nexus *nxp;
6419         int idx;
6420
6421         if (isp->isp_type < ISP_HA_FC_2300)
6422                 return (0);
6423
6424         chan = XS_CHANNEL(cmd);
6425         tgt = XS_TGT(cmd);
6426         lun = XS_LUN(cmd);
6427         fc = &isp->isp_osinfo.pc.fc[chan];
6428         idx = NEXUS_HASH(tgt, lun);
6429         nxp = fc->nexus_hash[idx];
6430
6431         while (nxp) {
6432                 if (nxp->tgt == tgt && nxp->lun == lun)
6433                         break;
6434                 nxp = nxp->next;
6435         }
6436         if (nxp == NULL) {
6437                 nxp = fc->nexus_free_list;
6438                 if (nxp == NULL) {
6439                         nxp = malloc(sizeof (struct isp_nexus), M_DEVBUF, M_ZERO|M_NOWAIT);
6440                         if (nxp == NULL) {
6441                                 return (-1);
6442                         }
6443                 } else {
6444                         fc->nexus_free_list = nxp->next;
6445                 }
6446                 nxp->tgt = tgt;
6447                 nxp->lun = lun;
6448                 nxp->next = fc->nexus_hash[idx];
6449                 fc->nexus_hash[idx] = nxp;
6450         }
6451         if (nxp) {
6452                 if (nxp->crnseed == 0)
6453                         nxp->crnseed = 1;
6454                 if (cmd)
6455                         PISP_PCMD(cmd)->crn = nxp->crnseed;
6456                 *crnp = nxp->crnseed++;
6457                 return (0);
6458         }
6459         return (-1);
6460 }
6461
6462 /*
6463  * We enter with the lock held
6464  */
6465 void
6466 isp_timer(void *arg)
6467 {
6468         ispsoftc_t *isp = arg;
6469 #ifdef  ISP_TARGET_MODE
6470         isp_tmcmd_restart(isp);
6471 #endif
6472         callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp);
6473 }
6474
6475 isp_ecmd_t *
6476 isp_get_ecmd(ispsoftc_t *isp)
6477 {
6478         isp_ecmd_t *ecmd = isp->isp_osinfo.ecmd_free;
6479         if (ecmd) {
6480                 isp->isp_osinfo.ecmd_free = ecmd->next;
6481         }
6482         return (ecmd);
6483 }
6484
6485 void
6486 isp_put_ecmd(ispsoftc_t *isp, isp_ecmd_t *ecmd)
6487 {
6488         ecmd->next = isp->isp_osinfo.ecmd_free;
6489         isp->isp_osinfo.ecmd_free = ecmd;
6490 }