]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/isp/isp_freebsd.c
Update compiler-rt to trunk r224034. This brings a number of new
[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, fcportdb_t *fcp, 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
4592         /*
4593          * Since we're about to issue a rescan, mark this device as not
4594          * reported gone.
4595          */
4596         fcp->reported_gone = 0;
4597
4598         xpt_rescan(ccb);
4599 }
4600
4601 static void
4602 isp_make_gone(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt)
4603 {
4604         struct cam_path *tp;
4605         struct isp_fc *fc = ISP_FC_PC(isp, chan);
4606
4607         if (isp_autoconfig == 0) {
4608                 return;
4609         }
4610         if (xpt_create_path(&tp, NULL, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
4611                 /*
4612                  * We're about to send out the lost device async
4613                  * notification, so indicate that we have reported it gone.
4614                  */
4615                 fcp->reported_gone = 1;
4616                 xpt_async(AC_LOST_DEVICE, tp, NULL);
4617                 xpt_free_path(tp);
4618         }
4619 }
4620
4621 /*
4622  * Gone Device Timer Function- when we have decided that a device has gone
4623  * away, we wait a specific period of time prior to telling the OS it has
4624  * gone away.
4625  *
4626  * This timer function fires once a second and then scans the port database
4627  * for devices that are marked dead but still have a virtual target assigned.
4628  * We decrement a counter for that port database entry, and when it hits zero,
4629  * we tell the OS the device has gone away.
4630  */
4631 static void
4632 isp_gdt(void *arg)
4633 {
4634         struct isp_fc *fc = arg;
4635         taskqueue_enqueue(taskqueue_thread, &fc->gtask);
4636 }
4637
4638 static void
4639 isp_gdt_task(void *arg, int pending)
4640 {
4641         struct isp_fc *fc = arg;
4642         ispsoftc_t *isp = fc->isp;
4643         int chan = fc - isp->isp_osinfo.pc.fc;
4644         fcportdb_t *lp;
4645         int dbidx, tgt, more_to_do = 0;
4646
4647         ISP_LOCK(isp);
4648         isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GDT timer expired", chan);
4649         for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
4650                 lp = &FCPARAM(isp, chan)->portdb[dbidx];
4651
4652                 if (lp->state != FC_PORTDB_STATE_ZOMBIE) {
4653                         continue;
4654                 }
4655                 if (lp->dev_map_idx == 0 || lp->target_mode) {
4656                         continue;
4657                 }
4658                 if (lp->gone_timer != 0) {
4659                         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);
4660                         lp->gone_timer -= 1;
4661                         more_to_do++;
4662                         continue;
4663                 }
4664                 tgt = lp->dev_map_idx - 1;
4665                 FCPARAM(isp, chan)->isp_dev_map[tgt] = 0;
4666                 lp->dev_map_idx = 0;
4667                 lp->state = FC_PORTDB_STATE_NIL;
4668                 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, tgt, "Gone Device Timeout");
4669                 isp_make_gone(isp, lp, chan, tgt);
4670         }
4671         if (fc->ready) {
4672                 if (more_to_do) {
4673                         callout_reset(&fc->gdt, hz, isp_gdt, fc);
4674                 } else {
4675                         callout_deactivate(&fc->gdt);
4676                         isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Stopping Gone Device Timer @ %lu", chan, (unsigned long) time_uptime);
4677                 }
4678         }
4679         ISP_UNLOCK(isp);
4680 }
4681
4682 /*
4683  * Loop Down Timer Function- when loop goes down, a timer is started and
4684  * and after it expires we come here and take all probational devices that
4685  * the OS knows about and the tell the OS that they've gone away.
4686  * 
4687  * We don't clear the devices out of our port database because, when loop
4688  * come back up, we have to do some actual cleanup with the chip at that
4689  * point (implicit PLOGO, e.g., to get the chip's port database state right).
4690  */
4691 static void
4692 isp_ldt(void *arg)
4693 {
4694         struct isp_fc *fc = arg;
4695         taskqueue_enqueue(taskqueue_thread, &fc->ltask);
4696 }
4697
4698 static void
4699 isp_ldt_task(void *arg, int pending)
4700 {
4701         struct isp_fc *fc = arg;
4702         ispsoftc_t *isp = fc->isp;
4703         int chan = fc - isp->isp_osinfo.pc.fc;
4704         fcportdb_t *lp;
4705         int dbidx, tgt, i;
4706
4707         ISP_LOCK(isp);
4708         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop Down Timer expired @ %lu", chan, (unsigned long) time_uptime);
4709         callout_deactivate(&fc->ldt);
4710
4711         /*
4712          * Notify to the OS all targets who we now consider have departed.
4713          */
4714         for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
4715                 lp = &FCPARAM(isp, chan)->portdb[dbidx];
4716
4717                 if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
4718                         continue;
4719                 }
4720                 if (lp->dev_map_idx == 0 || lp->target_mode) {
4721                         continue;
4722                 }
4723
4724                 /*
4725                  * XXX: CLEAN UP AND COMPLETE ANY PENDING COMMANDS FIRST!
4726                  */
4727
4728
4729                 for (i = 0; i < isp->isp_maxcmds; i++) {
4730                         struct ccb_scsiio *xs;
4731
4732                         if (!ISP_VALID_HANDLE(isp, isp->isp_xflist[i].handle)) {
4733                                 continue;
4734                         }
4735                         if ((xs = isp->isp_xflist[i].cmd) == NULL) {
4736                                 continue;
4737                         }
4738                         if (dbidx != (FCPARAM(isp, chan)->isp_dev_map[XS_TGT(xs)] - 1)) {
4739                                 continue;
4740                         }
4741                         isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%d orphaned by loop down timeout",
4742                             isp->isp_xflist[i].handle, chan, XS_TGT(xs), XS_LUN(xs));
4743                 }
4744
4745                 /*
4746                  * Mark that we've announced that this device is gone....
4747                  */
4748                 lp->announced = 1;
4749
4750                 /*
4751                  * but *don't* change the state of the entry. Just clear
4752                  * any target id stuff and announce to CAM that the
4753                  * device is gone. This way any necessary PLOGO stuff
4754                  * will happen when loop comes back up.
4755                  */
4756
4757                 tgt = lp->dev_map_idx - 1;
4758                 FCPARAM(isp, chan)->isp_dev_map[tgt] = 0;
4759                 lp->dev_map_idx = 0;
4760                 lp->state = FC_PORTDB_STATE_NIL;
4761                 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, tgt, "Loop Down Timeout");
4762                 isp_make_gone(isp, lp, chan, tgt);
4763         }
4764
4765         if (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR) {
4766                 isp_unfreeze_loopdown(isp, chan);
4767         }
4768         /*
4769          * The loop down timer has expired. Wake up the kthread
4770          * to notice that fact (or make it false).
4771          */
4772         fc->loop_dead = 1;
4773         fc->loop_down_time = fc->loop_down_limit+1;
4774         wakeup(fc);
4775         ISP_UNLOCK(isp);
4776 }
4777
4778 static void
4779 isp_kthread(void *arg)
4780 {
4781         struct isp_fc *fc = arg;
4782         ispsoftc_t *isp = fc->isp;
4783         int chan = fc - isp->isp_osinfo.pc.fc;
4784         int slp = 0;
4785
4786         mtx_lock(&isp->isp_osinfo.lock);
4787
4788         while (isp->isp_osinfo.is_exiting == 0) {
4789                 int lb, lim;
4790
4791                 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d checking FC state", __func__, chan);
4792                 lb = isp_fc_runstate(isp, chan, 250000);
4793
4794                 /*
4795                  * Our action is different based upon whether we're supporting
4796                  * Initiator mode or not. If we are, we might freeze the simq
4797                  * when loop is down and set all sorts of different delays to
4798                  * check again.
4799                  *
4800                  * If not, we simply just wait for loop to come up.
4801                  */
4802                 if (lb && (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR)) {
4803                         /*
4804                          * Increment loop down time by the last sleep interval
4805                          */
4806                         fc->loop_down_time += slp;
4807
4808                         if (lb < 0) {
4809                                 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC loop not up (down count %d)", __func__, chan, fc->loop_down_time);
4810                         } else {
4811                                 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);
4812                         }
4813
4814                         /*
4815                          * If we've never seen loop up and we've waited longer
4816                          * than quickboot time, or we've seen loop up but we've
4817                          * waited longer than loop_down_limit, give up and go
4818                          * to sleep until loop comes up.
4819                          */
4820                         if (FCPARAM(isp, chan)->loop_seen_once == 0) {
4821                                 lim = isp_quickboot_time;
4822                         } else {
4823                                 lim = fc->loop_down_limit;
4824                         }
4825                         if (fc->loop_down_time >= lim) {
4826                                 isp_freeze_loopdown(isp, chan, "loop limit hit");
4827                                 slp = 0;
4828                         } else if (fc->loop_down_time < 10) {
4829                                 slp = 1;
4830                         } else if (fc->loop_down_time < 30) {
4831                                 slp = 5;
4832                         } else if (fc->loop_down_time < 60) {
4833                                 slp = 10;
4834                         } else if (fc->loop_down_time < 120) {
4835                                 slp = 20;
4836                         } else {
4837                                 slp = 30;
4838                         }
4839
4840                 } else if (lb) {
4841                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC Loop Down", __func__, chan);
4842                         fc->loop_down_time += slp;
4843                         if (fc->loop_down_time > 300)
4844                                 slp = 0;
4845                         else
4846                                 slp = 60;
4847                 } else {
4848                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC state OK", __func__, chan);
4849                         fc->loop_down_time = 0;
4850                         slp = 0;
4851                 }
4852
4853
4854                 /*
4855                  * If this is past the first loop up or the loop is dead and if we'd frozen the simq, unfreeze it
4856                  * now so that CAM can start sending us commands.
4857                  *
4858                  * If the FC state isn't okay yet, they'll hit that in isp_start which will freeze the queue again
4859                  * or kill the commands, as appropriate.
4860                  */
4861
4862                 if (FCPARAM(isp, chan)->loop_seen_once || fc->loop_dead) {
4863                         isp_unfreeze_loopdown(isp, chan);
4864                 }
4865
4866                 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep time %d", __func__, chan, slp);
4867
4868                 msleep(fc, &isp->isp_osinfo.lock, PRIBIO, "ispf", slp * hz);
4869
4870                 /*
4871                  * If slp is zero, we're waking up for the first time after
4872                  * things have been okay. In this case, we set a deferral state
4873                  * for all commands and delay hysteresis seconds before starting
4874                  * the FC state evaluation. This gives the loop/fabric a chance
4875                  * to settle.
4876                  */
4877                 if (slp == 0 && fc->hysteresis) {
4878                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep hysteresis ticks %d", __func__, chan, fc->hysteresis * hz);
4879                         mtx_unlock(&isp->isp_osinfo.lock);
4880                         pause("ispt", fc->hysteresis * hz);
4881                         mtx_lock(&isp->isp_osinfo.lock);
4882                 }
4883         }
4884         fc->num_threads -= 1;
4885         mtx_unlock(&isp->isp_osinfo.lock);
4886         kthread_exit();
4887 }
4888
4889 static void
4890 isp_action(struct cam_sim *sim, union ccb *ccb)
4891 {
4892         int bus, tgt, ts, error, lim;
4893         ispsoftc_t *isp;
4894         struct ccb_trans_settings *cts;
4895
4896         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
4897
4898         isp = (ispsoftc_t *)cam_sim_softc(sim);
4899         mtx_assert(&isp->isp_lock, MA_OWNED);
4900
4901         if (isp->isp_state != ISP_RUNSTATE && ccb->ccb_h.func_code == XPT_SCSI_IO) {
4902                 isp_init(isp);
4903                 if (isp->isp_state != ISP_INITSTATE) {
4904                         /*
4905                          * Lie. Say it was a selection timeout.
4906                          */
4907                         ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
4908                         xpt_freeze_devq(ccb->ccb_h.path, 1);
4909                         xpt_done(ccb);
4910                         return;
4911                 }
4912                 isp->isp_state = ISP_RUNSTATE;
4913         }
4914         isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
4915         ISP_PCMD(ccb) = NULL;
4916
4917         switch (ccb->ccb_h.func_code) {
4918         case XPT_SCSI_IO:       /* Execute the requested I/O operation */
4919                 bus = XS_CHANNEL(ccb);
4920                 /*
4921                  * Do a couple of preliminary checks...
4922                  */
4923                 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
4924                         if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
4925                                 ccb->ccb_h.status = CAM_REQ_INVALID;
4926                                 xpt_done(ccb);
4927                                 break;
4928                         }
4929                 }
4930                 ccb->csio.req_map = NULL;
4931 #ifdef  DIAGNOSTIC
4932                 if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) {
4933                         xpt_print(ccb->ccb_h.path, "invalid target\n");
4934                         ccb->ccb_h.status = CAM_PATH_INVALID;
4935                 } else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) {
4936                         xpt_print(ccb->ccb_h.path, "invalid lun\n");
4937                         ccb->ccb_h.status = CAM_PATH_INVALID;
4938                 }
4939                 if (ccb->ccb_h.status == CAM_PATH_INVALID) {
4940                         xpt_done(ccb);
4941                         break;
4942                 }
4943 #endif
4944                 ccb->csio.scsi_status = SCSI_STATUS_OK;
4945                 if (isp_get_pcmd(isp, ccb)) {
4946                         isp_prt(isp, ISP_LOGWARN, "out of PCMDs");
4947                         cam_freeze_devq(ccb->ccb_h.path);
4948                         cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
4949                         xpt_done(ccb);
4950                         break;
4951                 }
4952                 error = isp_start((XS_T *) ccb);
4953                 switch (error) {
4954                 case CMD_QUEUED:
4955                         ccb->ccb_h.status |= CAM_SIM_QUEUED;
4956                         if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
4957                                 break;
4958                         }
4959                         ts = ccb->ccb_h.timeout;
4960                         if (ts == CAM_TIME_DEFAULT) {
4961                                 ts = 60*1000;
4962                         }
4963                         ts = isp_mstohz(ts);
4964                         callout_reset(&PISP_PCMD(ccb)->wdog, ts, isp_watchdog, ccb);
4965                         break;
4966                 case CMD_RQLATER:
4967                         /*
4968                          * We get this result for FC devices if the loop state isn't ready yet
4969                          * or if the device in question has gone zombie on us.
4970                          *
4971                          * If we've never seen Loop UP at all, we requeue this request and wait
4972                          * for the initial loop up delay to expire.
4973                          */
4974                         lim = ISP_FC_PC(isp, bus)->loop_down_limit;
4975                         if (FCPARAM(isp, bus)->loop_seen_once == 0 || ISP_FC_PC(isp, bus)->loop_down_time >= lim) {
4976                                 if (FCPARAM(isp, bus)->loop_seen_once == 0) {
4977                                         isp_prt(isp, ISP_LOGDEBUG0, "%d.%d loop not seen yet @ %lu", XS_TGT(ccb), XS_LUN(ccb), (unsigned long) time_uptime);
4978                                 } else {
4979                                         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);
4980                                 }
4981                                 ccb->ccb_h.status = CAM_SEL_TIMEOUT|CAM_DEV_QFRZN;
4982                                 xpt_freeze_devq(ccb->ccb_h.path, 1);
4983                                 isp_free_pcmd(isp, ccb);
4984                                 xpt_done(ccb);
4985                                 break;
4986                         }
4987                         isp_prt(isp, ISP_LOGDEBUG0, "%d.%d retry later", XS_TGT(ccb), XS_LUN(ccb));
4988                         cam_freeze_devq(ccb->ccb_h.path);
4989                         cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
4990                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
4991                         isp_free_pcmd(isp, ccb);
4992                         xpt_done(ccb);
4993                         break;
4994                 case CMD_EAGAIN:
4995                         isp_free_pcmd(isp, ccb);
4996                         cam_freeze_devq(ccb->ccb_h.path);
4997                         cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0);
4998                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
4999                         xpt_done(ccb);
5000                         break;
5001                 case CMD_COMPLETE:
5002                         isp_done((struct ccb_scsiio *) ccb);
5003                         break;
5004                 default:
5005                         isp_prt(isp, ISP_LOGERR, "What's this? 0x%x at %d in file %s", error, __LINE__, __FILE__);
5006                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
5007                         isp_free_pcmd(isp, ccb);
5008                         xpt_done(ccb);
5009                 }
5010                 break;
5011
5012 #ifdef  ISP_TARGET_MODE
5013         case XPT_EN_LUN:                /* Enable/Disable LUN as a target */
5014                 if (ccb->cel.enable) {
5015                         isp_enable_lun(isp, ccb);
5016                 } else {
5017                         isp_disable_lun(isp, ccb);
5018                 }
5019                 break;
5020         case XPT_IMMED_NOTIFY:
5021         case XPT_IMMEDIATE_NOTIFY:      /* Add Immediate Notify Resource */
5022         case XPT_ACCEPT_TARGET_IO:      /* Add Accept Target IO Resource */
5023         {
5024                 tstate_t *tptr = get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
5025                 if (tptr == NULL) {
5026                         tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
5027                 }
5028                 if (tptr == NULL) {
5029                         const char *str;
5030                         uint32_t tag;
5031
5032                         if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
5033                                 str = "XPT_IMMEDIATE_NOTIFY";
5034                                 tag = ccb->cin1.seq_id;
5035                         } else {
5036                                 tag = ccb->atio.tag_id;
5037                                 str = "XPT_ACCEPT_TARGET_IO";
5038                         }
5039                         ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] no state pointer found for %s\n", __func__, tag, str);
5040                         dump_tstates(isp, XS_CHANNEL(ccb));
5041                         ccb->ccb_h.status = CAM_DEV_NOT_THERE;
5042                         break;
5043                 }
5044                 ccb->ccb_h.spriv_field0 = 0;
5045                 ccb->ccb_h.spriv_ptr1 = isp;
5046
5047                 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
5048                         if (ccb->atio.tag_id) {
5049                                 atio_private_data_t *atp = isp_find_atpd(isp, tptr, ccb->atio.tag_id);
5050                                 if (atp) {
5051                                         isp_put_atpd(isp, tptr, atp);
5052                                 }
5053                         }
5054                         tptr->atio_count++;
5055                         SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle);
5056                         ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE ATIO (tag id 0x%x), count now %d\n",
5057                             ccb->atio.tag_id, tptr->atio_count);
5058                         ccb->atio.tag_id = 0;
5059                 } else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
5060                         if (ccb->cin1.tag_id) {
5061                                 inot_private_data_t *ntp = isp_find_ntpd(isp, tptr, ccb->cin1.tag_id, ccb->cin1.seq_id);
5062                                 if (ntp) {
5063                                         isp_put_ntpd(isp, tptr, ntp);
5064                                 }
5065                         }
5066                         tptr->inot_count++;
5067                         SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
5068                         ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
5069                             ccb->cin1.seq_id, tptr->inot_count);
5070                         ccb->cin1.seq_id = 0;
5071                 } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
5072                         tptr->inot_count++;
5073                         SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
5074                         ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
5075                             ccb->cin1.seq_id, tptr->inot_count);
5076                         ccb->cin1.seq_id = 0;
5077                 }
5078                 rls_lun_statep(isp, tptr);
5079                 ccb->ccb_h.status = CAM_REQ_INPROG;
5080                 break;
5081         }
5082         case XPT_NOTIFY_ACK:
5083                 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
5084                 break;
5085         case XPT_NOTIFY_ACKNOWLEDGE:            /* notify ack */
5086         {
5087                 tstate_t *tptr;
5088                 inot_private_data_t *ntp;
5089
5090                 /*
5091                  * XXX: Because we cannot guarantee that the path information in the notify acknowledge ccb
5092                  * XXX: matches that for the immediate notify, we have to *search* for the notify structure
5093                  */
5094                 /*
5095                  * All the relevant path information is in the associated immediate notify
5096                  */
5097                 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);
5098                 ntp = get_ntp_from_tagdata(isp, ccb->cna2.tag_id, ccb->cna2.seq_id, &tptr);
5099                 if (ntp == NULL) {
5100                         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__,
5101                              ccb->cna2.tag_id, ccb->cna2.seq_id);
5102                         ccb->ccb_h.status = CAM_DEV_NOT_THERE;
5103                         xpt_done(ccb);
5104                         break;
5105                 }
5106                 if (isp_handle_platform_target_notify_ack(isp, &ntp->rd.nt)) {
5107                         rls_lun_statep(isp, tptr);
5108                         cam_freeze_devq(ccb->ccb_h.path);
5109                         cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
5110                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
5111                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
5112                         break;
5113                 }
5114                 isp_put_ntpd(isp, tptr, ntp);
5115                 rls_lun_statep(isp, tptr);
5116                 ccb->ccb_h.status = CAM_REQ_CMP;
5117                 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);
5118                 xpt_done(ccb);
5119                 break;
5120         }
5121         case XPT_CONT_TARGET_IO:
5122                 isp_target_start_ctio(isp, ccb, FROM_CAM);
5123                 break;
5124 #endif
5125         case XPT_RESET_DEV:             /* BDR the specified SCSI device */
5126
5127                 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
5128                 tgt = ccb->ccb_h.target_id;
5129                 tgt |= (bus << 16);
5130
5131                 error = isp_control(isp, ISPCTL_RESET_DEV, bus, tgt);
5132                 if (error) {
5133                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
5134                 } else {
5135                         ccb->ccb_h.status = CAM_REQ_CMP;
5136                 }
5137                 xpt_done(ccb);
5138                 break;
5139         case XPT_ABORT:                 /* Abort the specified CCB */
5140         {
5141                 union ccb *accb = ccb->cab.abort_ccb;
5142                 switch (accb->ccb_h.func_code) {
5143 #ifdef  ISP_TARGET_MODE
5144                 case XPT_ACCEPT_TARGET_IO:
5145                         isp_target_mark_aborted(isp, ccb);
5146                         break;
5147 #endif
5148                 case XPT_SCSI_IO:
5149                         error = isp_control(isp, ISPCTL_ABORT_CMD, accb);
5150                         if (error) {
5151                                 ccb->ccb_h.status = CAM_UA_ABORT;
5152                         } else {
5153                                 ccb->ccb_h.status = CAM_REQ_CMP;
5154                         }
5155                         break;
5156                 default:
5157                         ccb->ccb_h.status = CAM_REQ_INVALID;
5158                         break;
5159                 }
5160                 /*
5161                  * This is not a queued CCB, so the caller expects it to be
5162                  * complete when control is returned.
5163                  */
5164                 break;
5165         }
5166 #define IS_CURRENT_SETTINGS(c)  (c->type == CTS_TYPE_CURRENT_SETTINGS)
5167         case XPT_SET_TRAN_SETTINGS:     /* Nexus Settings */
5168                 cts = &ccb->cts;
5169                 if (!IS_CURRENT_SETTINGS(cts)) {
5170                         ccb->ccb_h.status = CAM_REQ_INVALID;
5171                         xpt_done(ccb);
5172                         break;
5173                 }
5174                 tgt = cts->ccb_h.target_id;
5175                 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
5176                 if (IS_SCSI(isp)) {
5177                         struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
5178                         struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
5179                         sdparam *sdp = SDPARAM(isp, bus);
5180                         uint16_t *dptr;
5181
5182                         if (spi->valid == 0 && scsi->valid == 0) {
5183                                 ccb->ccb_h.status = CAM_REQ_CMP;
5184                                 xpt_done(ccb);
5185                                 break;
5186                         }
5187
5188                         /*
5189                          * We always update (internally) from goal_flags
5190                          * so any request to change settings just gets
5191                          * vectored to that location.
5192                          */
5193                         dptr = &sdp->isp_devparam[tgt].goal_flags;
5194
5195                         if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
5196                                 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
5197                                         *dptr |= DPARM_DISC;
5198                                 else
5199                                         *dptr &= ~DPARM_DISC;
5200                         }
5201
5202                         if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
5203                                 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
5204                                         *dptr |= DPARM_TQING;
5205                                 else
5206                                         *dptr &= ~DPARM_TQING;
5207                         }
5208
5209                         if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
5210                                 if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
5211                                         *dptr |= DPARM_WIDE;
5212                                 else
5213                                         *dptr &= ~DPARM_WIDE;
5214                         }
5215
5216                         /*
5217                          * XXX: FIX ME
5218                          */
5219                         if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) && (spi->valid & CTS_SPI_VALID_SYNC_RATE) && (spi->sync_period && spi->sync_offset)) {
5220                                 *dptr |= DPARM_SYNC;
5221                                 /*
5222                                  * XXX: CHECK FOR LEGALITY
5223                                  */
5224                                 sdp->isp_devparam[tgt].goal_period = spi->sync_period;
5225                                 sdp->isp_devparam[tgt].goal_offset = spi->sync_offset;
5226                         } else {
5227                                 *dptr &= ~DPARM_SYNC;
5228                         }
5229                         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,
5230                             sdp->isp_devparam[tgt].goal_offset, sdp->isp_devparam[tgt].goal_period);
5231                         sdp->isp_devparam[tgt].dev_update = 1;
5232                         sdp->update = 1;
5233                 }
5234                 ccb->ccb_h.status = CAM_REQ_CMP;
5235                 xpt_done(ccb);
5236                 break;
5237         case XPT_GET_TRAN_SETTINGS:
5238                 cts = &ccb->cts;
5239                 tgt = cts->ccb_h.target_id;
5240                 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
5241                 if (IS_FC(isp)) {
5242                         fcparam *fcp = FCPARAM(isp, bus);
5243                         struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
5244                         struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
5245                         unsigned int hdlidx;
5246
5247                         cts->protocol = PROTO_SCSI;
5248                         cts->protocol_version = SCSI_REV_2;
5249                         cts->transport = XPORT_FC;
5250                         cts->transport_version = 0;
5251
5252                         scsi->valid = CTS_SCSI_VALID_TQ;
5253                         scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
5254                         fc->valid = CTS_FC_VALID_SPEED;
5255                         fc->bitrate = 100000;
5256                         fc->bitrate *= fcp->isp_gbspeed;
5257                         hdlidx = fcp->isp_dev_map[tgt] - 1;
5258                         if (hdlidx < MAX_FC_TARG) {
5259                                 fcportdb_t *lp = &fcp->portdb[hdlidx];
5260                                 fc->wwnn = lp->node_wwn;
5261                                 fc->wwpn = lp->port_wwn;
5262                                 fc->port = lp->portid;
5263                                 fc->valid |= CTS_FC_VALID_WWNN | CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT;
5264                         }
5265                 } else {
5266                         struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
5267                         struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
5268                         sdparam *sdp = SDPARAM(isp, bus);
5269                         uint16_t dval, pval, oval;
5270
5271                         if (IS_CURRENT_SETTINGS(cts)) {
5272                                 sdp->isp_devparam[tgt].dev_refresh = 1;
5273                                 sdp->update = 1;
5274                                 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus);
5275                                 dval = sdp->isp_devparam[tgt].actv_flags;
5276                                 oval = sdp->isp_devparam[tgt].actv_offset;
5277                                 pval = sdp->isp_devparam[tgt].actv_period;
5278                         } else {
5279                                 dval = sdp->isp_devparam[tgt].nvrm_flags;
5280                                 oval = sdp->isp_devparam[tgt].nvrm_offset;
5281                                 pval = sdp->isp_devparam[tgt].nvrm_period;
5282                         }
5283
5284                         cts->protocol = PROTO_SCSI;
5285                         cts->protocol_version = SCSI_REV_2;
5286                         cts->transport = XPORT_SPI;
5287                         cts->transport_version = 2;
5288
5289                         spi->valid = 0;
5290                         scsi->valid = 0;
5291                         spi->flags = 0;
5292                         scsi->flags = 0;
5293                         if (dval & DPARM_DISC) {
5294                                 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5295                         }
5296                         if ((dval & DPARM_SYNC) && oval && pval) {
5297                                 spi->sync_offset = oval;
5298                                 spi->sync_period = pval;
5299                         } else {
5300                                 spi->sync_offset = 0;
5301                                 spi->sync_period = 0;
5302                         }
5303                         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5304                         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5305                         spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5306                         if (dval & DPARM_WIDE) {
5307                                 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
5308                         } else {
5309                                 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
5310                         }
5311                         if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
5312                                 scsi->valid = CTS_SCSI_VALID_TQ;
5313                                 if (dval & DPARM_TQING) {
5314                                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5315                                 }
5316                                 spi->valid |= CTS_SPI_VALID_DISC;
5317                         }
5318                         isp_prt(isp, ISP_LOGDEBUG0, "GET %s (%d.%d.%jx) to flags %x off %x per %x", IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
5319                             bus, tgt, (uintmax_t)cts->ccb_h.target_lun, dval, oval, pval);
5320                 }
5321                 ccb->ccb_h.status = CAM_REQ_CMP;
5322                 xpt_done(ccb);
5323                 break;
5324
5325         case XPT_CALC_GEOMETRY:
5326                 cam_calc_geometry(&ccb->ccg, 1);
5327                 xpt_done(ccb);
5328                 break;
5329
5330         case XPT_RESET_BUS:             /* Reset the specified bus */
5331                 bus = cam_sim_bus(sim);
5332                 error = isp_control(isp, ISPCTL_RESET_BUS, bus);
5333                 if (error) {
5334                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
5335                         xpt_done(ccb);
5336                         break;
5337                 }
5338                 if (bootverbose) {
5339                         xpt_print(ccb->ccb_h.path, "reset bus on channel %d\n", bus);
5340                 }
5341                 if (IS_FC(isp)) {
5342                         xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, 0);
5343                 } else {
5344                         xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, 0);
5345                 }
5346                 ccb->ccb_h.status = CAM_REQ_CMP;
5347                 xpt_done(ccb);
5348                 break;
5349
5350         case XPT_TERM_IO:               /* Terminate the I/O process */
5351                 ccb->ccb_h.status = CAM_REQ_INVALID;
5352                 xpt_done(ccb);
5353                 break;
5354
5355         case XPT_SET_SIM_KNOB:          /* Set SIM knobs */
5356         {
5357                 struct ccb_sim_knob *kp = &ccb->knob;
5358                 fcparam *fcp;
5359
5360                 if (!IS_FC(isp)) {
5361                         ccb->ccb_h.status = CAM_REQ_INVALID;
5362                         xpt_done(ccb);
5363                         break;
5364                 }
5365
5366                 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
5367                 fcp = FCPARAM(isp, bus);
5368
5369                 if (kp->xport_specific.fc.valid & KNOB_VALID_ADDRESS) {
5370                         fcp->isp_wwnn = ISP_FC_PC(isp, bus)->def_wwnn = kp->xport_specific.fc.wwnn;
5371                         fcp->isp_wwpn = ISP_FC_PC(isp, bus)->def_wwpn = kp->xport_specific.fc.wwpn;
5372                         isp_prt(isp, ISP_LOGALL, "Setting Channel %d wwns to 0x%jx 0x%jx", bus, fcp->isp_wwnn, fcp->isp_wwpn);
5373                 }
5374                 ccb->ccb_h.status = CAM_REQ_CMP;
5375                 if (kp->xport_specific.fc.valid & KNOB_VALID_ROLE) {
5376                         int rchange = 0;
5377                         int newrole = 0;
5378
5379                         switch (kp->xport_specific.fc.role) {
5380                         case KNOB_ROLE_NONE:
5381                                 if (fcp->role != ISP_ROLE_NONE) {
5382                                         rchange = 1;
5383                                         newrole = ISP_ROLE_NONE;
5384                                 }
5385                                 break;
5386                         case KNOB_ROLE_TARGET:
5387                                 if (fcp->role != ISP_ROLE_TARGET) {
5388                                         rchange = 1;
5389                                         newrole = ISP_ROLE_TARGET;
5390                                 }
5391                                 break;
5392                         case KNOB_ROLE_INITIATOR:
5393                                 if (fcp->role != ISP_ROLE_INITIATOR) {
5394                                         rchange = 1;
5395                                         newrole = ISP_ROLE_INITIATOR;
5396                                 }
5397                                 break;
5398                         case KNOB_ROLE_BOTH:
5399 #if 0
5400                                 if (fcp->role != ISP_ROLE_BOTH) {
5401                                         rchange = 1;
5402                                         newrole = ISP_ROLE_BOTH;
5403                                 }
5404 #else
5405                                 /*
5406                                  * We don't really support dual role at present on FC cards.
5407                                  *
5408                                  * We should, but a bunch of things are currently broken,
5409                                  * so don't allow it.
5410                                  */
5411                                 isp_prt(isp, ISP_LOGERR, "cannot support dual role at present");
5412                                 ccb->ccb_h.status = CAM_REQ_INVALID;
5413 #endif
5414                                 break;
5415                         }
5416                         if (rchange) {
5417                                 ISP_PATH_PRT(isp, ISP_LOGCONFIG, ccb->ccb_h.path, "changing role on from %d to %d\n", fcp->role, newrole);
5418 #ifdef  ISP_TARGET_MODE
5419                                 ISP_SET_PC(isp, bus, tm_enabled, 0);
5420                                 ISP_SET_PC(isp, bus, tm_luns_enabled, 0);
5421 #endif
5422                                 if (isp_fc_change_role(isp, bus, newrole) != 0) {
5423                                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
5424                                         xpt_done(ccb);
5425                                         break;
5426                                 }
5427 #ifdef  ISP_TARGET_MODE
5428                                 if (newrole == ISP_ROLE_TARGET || newrole == ISP_ROLE_BOTH) {
5429                                         /*
5430                                          * Give the new role a chance to complain and settle
5431                                          */
5432                                         msleep(isp, &isp->isp_lock, PRIBIO, "taking a breather", 2);
5433                                         ccb->ccb_h.status = isp_enable_deferred_luns(isp, bus);
5434                                 }
5435 #endif
5436                         }
5437                 }
5438                 xpt_done(ccb);
5439                 break;
5440         }
5441         case XPT_GET_SIM_KNOB:          /* Get SIM knobs */
5442         {
5443                 struct ccb_sim_knob *kp = &ccb->knob;
5444
5445                 if (IS_FC(isp)) {
5446                         fcparam *fcp;
5447
5448                         bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
5449                         fcp = FCPARAM(isp, bus);
5450
5451                         kp->xport_specific.fc.wwnn = fcp->isp_wwnn;
5452                         kp->xport_specific.fc.wwpn = fcp->isp_wwpn;
5453                         switch (fcp->role) {
5454                         case ISP_ROLE_NONE:
5455                                 kp->xport_specific.fc.role = KNOB_ROLE_NONE;
5456                                 break;
5457                         case ISP_ROLE_TARGET:
5458                                 kp->xport_specific.fc.role = KNOB_ROLE_TARGET;
5459                                 break;
5460                         case ISP_ROLE_INITIATOR:
5461                                 kp->xport_specific.fc.role = KNOB_ROLE_INITIATOR;
5462                                 break;
5463                         case ISP_ROLE_BOTH:
5464                                 kp->xport_specific.fc.role = KNOB_ROLE_BOTH;
5465                                 break;
5466                         }
5467                         kp->xport_specific.fc.valid = KNOB_VALID_ADDRESS | KNOB_VALID_ROLE;
5468                         ccb->ccb_h.status = CAM_REQ_CMP;
5469                 } else {
5470                         ccb->ccb_h.status = CAM_REQ_INVALID;
5471                 }
5472                 xpt_done(ccb);
5473                 break;
5474         }
5475         case XPT_PATH_INQ:              /* Path routing inquiry */
5476         {
5477                 struct ccb_pathinq *cpi = &ccb->cpi;
5478
5479                 cpi->version_num = 1;
5480 #ifdef  ISP_TARGET_MODE
5481                 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
5482 #else
5483                 cpi->target_sprt = 0;
5484 #endif
5485                 cpi->hba_eng_cnt = 0;
5486                 cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
5487                 cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
5488                 cpi->bus_id = cam_sim_bus(sim);
5489                 if (isp->isp_osinfo.sixtyfourbit)
5490                         cpi->maxio = (ISP_NSEG64_MAX - 1) * PAGE_SIZE;
5491                 else
5492                         cpi->maxio = (ISP_NSEG_MAX - 1) * PAGE_SIZE;
5493
5494                 bus = cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
5495                 if (IS_FC(isp)) {
5496                         fcparam *fcp = FCPARAM(isp, bus);
5497
5498                         cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED;
5499
5500                         /*
5501                          * Because our loop ID can shift from time to time,
5502                          * make our initiator ID out of range of our bus.
5503                          */
5504                         cpi->initiator_id = cpi->max_target + 1;
5505
5506                         /*
5507                          * Set base transfer capabilities for Fibre Channel, for this HBA.
5508                          */
5509                         if (IS_25XX(isp)) {
5510                                 cpi->base_transfer_speed = 8000000;
5511                         } else if (IS_24XX(isp)) {
5512                                 cpi->base_transfer_speed = 4000000;
5513                         } else if (IS_23XX(isp)) {
5514                                 cpi->base_transfer_speed = 2000000;
5515                         } else {
5516                                 cpi->base_transfer_speed = 1000000;
5517                         }
5518                         cpi->hba_inquiry = PI_TAG_ABLE;
5519                         cpi->transport = XPORT_FC;
5520                         cpi->transport_version = 0;
5521                         cpi->xport_specific.fc.wwnn = fcp->isp_wwnn;
5522                         cpi->xport_specific.fc.wwpn = fcp->isp_wwpn;
5523                         cpi->xport_specific.fc.port = fcp->isp_portid;
5524                         cpi->xport_specific.fc.bitrate = fcp->isp_gbspeed * 1000;
5525                 } else {
5526                         sdparam *sdp = SDPARAM(isp, bus);
5527                         cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
5528                         cpi->hba_misc = PIM_UNMAPPED;
5529                         cpi->initiator_id = sdp->isp_initiator_id;
5530                         cpi->base_transfer_speed = 3300;
5531                         cpi->transport = XPORT_SPI;
5532                         cpi->transport_version = 2;
5533                 }
5534                 cpi->protocol = PROTO_SCSI;
5535                 cpi->protocol_version = SCSI_REV_2;
5536                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
5537                 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
5538                 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
5539                 cpi->unit_number = cam_sim_unit(sim);
5540                 cpi->ccb_h.status = CAM_REQ_CMP;
5541                 xpt_done(ccb);
5542                 break;
5543         }
5544         default:
5545                 ccb->ccb_h.status = CAM_REQ_INVALID;
5546                 xpt_done(ccb);
5547                 break;
5548         }
5549 }
5550
5551 #define ISPDDB  (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
5552
5553 void
5554 isp_done(XS_T *sccb)
5555 {
5556         ispsoftc_t *isp = XS_ISP(sccb);
5557         uint32_t status;
5558
5559         if (XS_NOERR(sccb))
5560                 XS_SETERR(sccb, CAM_REQ_CMP);
5561
5562         if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && (sccb->scsi_status != SCSI_STATUS_OK)) {
5563                 sccb->ccb_h.status &= ~CAM_STATUS_MASK;
5564                 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
5565                         sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
5566                 } else {
5567                         sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
5568                 }
5569         }
5570
5571         sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
5572         status = sccb->ccb_h.status & CAM_STATUS_MASK;
5573         if (status != CAM_REQ_CMP) {
5574                 if (status != CAM_SEL_TIMEOUT)
5575                         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);
5576                 else if ((IS_FC(isp))
5577                       && (XS_TGT(sccb) < MAX_FC_TARG)) {
5578                         fcparam *fcp;
5579                         int hdlidx;
5580
5581                         fcp = FCPARAM(isp, XS_CHANNEL(sccb));
5582                         hdlidx = fcp->isp_dev_map[XS_TGT(sccb)] - 1;
5583                         /*
5584                          * Note that we have reported that this device is
5585                          * gone.  If it reappears, we'll need to issue a
5586                          * rescan.
5587                          */
5588                         if (hdlidx > 0 && hdlidx < MAX_FC_TARG)
5589                                 fcp->portdb[hdlidx].reported_gone = 1;
5590                 }
5591                 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
5592                         sccb->ccb_h.status |= CAM_DEV_QFRZN;
5593                         xpt_freeze_devq(sccb->ccb_h.path, 1);
5594                 }
5595         }
5596
5597         if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) && (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5598                 xpt_print(sccb->ccb_h.path, "cam completion status 0x%x\n", sccb->ccb_h.status);
5599         }
5600
5601         if (callout_active(&PISP_PCMD(sccb)->wdog))
5602                 callout_stop(&PISP_PCMD(sccb)->wdog);
5603         isp_free_pcmd(isp, (union ccb *) sccb);
5604         xpt_done((union ccb *) sccb);
5605 }
5606
5607 void
5608 isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
5609 {
5610         int bus;
5611         static const char prom0[] = "Chan %d PortID 0x%06x handle 0x%x %s %s WWPN 0x%08x%08x";
5612         static const char prom2[] = "Chan %d PortID 0x%06x handle 0x%x %s %s tgt %u WWPN 0x%08x%08x";
5613         char buf[64];
5614         char *msg = NULL;
5615         target_id_t tgt;
5616         fcportdb_t *lp;
5617         struct isp_fc *fc;
5618         struct cam_path *tmppath;
5619         va_list ap;
5620
5621         switch (cmd) {
5622         case ISPASYNC_NEW_TGT_PARAMS:
5623         {
5624                 struct ccb_trans_settings_scsi *scsi;
5625                 struct ccb_trans_settings_spi *spi;
5626                 int flags, tgt;
5627                 sdparam *sdp;
5628                 struct ccb_trans_settings cts;
5629
5630                 memset(&cts, 0, sizeof (struct ccb_trans_settings));
5631
5632                 va_start(ap, cmd);
5633                 bus = va_arg(ap, int);
5634                 tgt = va_arg(ap, int);
5635                 va_end(ap);
5636                 sdp = SDPARAM(isp, bus);
5637
5638                 if (xpt_create_path(&tmppath, NULL, cam_sim_path(ISP_SPI_PC(isp, bus)->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
5639                         isp_prt(isp, ISP_LOGWARN, "isp_async cannot make temp path for %d.%d", tgt, bus);
5640                         break;
5641                 }
5642                 flags = sdp->isp_devparam[tgt].actv_flags;
5643                 cts.type = CTS_TYPE_CURRENT_SETTINGS;
5644                 cts.protocol = PROTO_SCSI;
5645                 cts.transport = XPORT_SPI;
5646
5647                 scsi = &cts.proto_specific.scsi;
5648                 spi = &cts.xport_specific.spi;
5649
5650                 if (flags & DPARM_TQING) {
5651                         scsi->valid |= CTS_SCSI_VALID_TQ;
5652                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5653                 }
5654
5655                 if (flags & DPARM_DISC) {
5656                         spi->valid |= CTS_SPI_VALID_DISC;
5657                         spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5658                 }
5659                 spi->flags |= CTS_SPI_VALID_BUS_WIDTH;
5660                 if (flags & DPARM_WIDE) {
5661                         spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
5662                 } else {
5663                         spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
5664                 }
5665                 if (flags & DPARM_SYNC) {
5666                         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5667                         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5668                         spi->sync_period = sdp->isp_devparam[tgt].actv_period;
5669                         spi->sync_offset = sdp->isp_devparam[tgt].actv_offset;
5670                 }
5671                 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);
5672                 xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
5673                 xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
5674                 xpt_free_path(tmppath);
5675                 break;
5676         }
5677         case ISPASYNC_BUS_RESET:
5678         {
5679                 va_start(ap, cmd);
5680                 bus = va_arg(ap, int);
5681                 va_end(ap);
5682                 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected", bus);
5683                 if (IS_FC(isp)) {
5684                         xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, NULL);
5685                 } else {
5686                         xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, NULL);
5687                 }
5688                 break;
5689         }
5690         case ISPASYNC_LIP:
5691                 if (msg == NULL) {
5692                         msg = "LIP Received";
5693                 }
5694                 /* FALLTHROUGH */
5695         case ISPASYNC_LOOP_RESET:
5696                 if (msg == NULL) {
5697                         msg = "LOOP Reset";
5698                 }
5699                 /* FALLTHROUGH */
5700         case ISPASYNC_LOOP_DOWN:
5701         {
5702                 if (msg == NULL) {
5703                         msg = "LOOP Down";
5704                 }
5705                 va_start(ap, cmd);
5706                 bus = va_arg(ap, int);
5707                 va_end(ap);
5708
5709                 FCPARAM(isp, bus)->link_active = 0;
5710
5711                 fc = ISP_FC_PC(isp, bus);
5712                 if (cmd == ISPASYNC_LOOP_DOWN && fc->ready) {
5713                         /*
5714                          * We don't do any simq freezing if we are only in target mode
5715                          */
5716                         if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
5717                                 if (fc->path) {
5718                                         isp_freeze_loopdown(isp, bus, msg);
5719                                 }
5720                                 if (!callout_active(&fc->ldt)) {
5721                                         callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc);
5722                                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Loop Down Timer @ %lu", (unsigned long) time_uptime);
5723                                 }
5724                         }
5725                 }
5726                 isp_fcp_reset_crn(fc, /*tgt*/0, /*tgt_set*/ 0);
5727
5728                 isp_prt(isp, ISP_LOGINFO, "Chan %d: %s", bus, msg);
5729                 break;
5730         }
5731         case ISPASYNC_LOOP_UP:
5732                 va_start(ap, cmd);
5733                 bus = va_arg(ap, int);
5734                 va_end(ap);
5735                 fc = ISP_FC_PC(isp, bus);
5736                 /*
5737                  * Now we just note that Loop has come up. We don't
5738                  * actually do anything because we're waiting for a
5739                  * Change Notify before activating the FC cleanup
5740                  * thread to look at the state of the loop again.
5741                  */
5742                 FCPARAM(isp, bus)->link_active = 1;
5743                 fc->loop_dead = 0;
5744                 fc->loop_down_time = 0;
5745                 isp_prt(isp, ISP_LOGINFO, "Chan %d Loop UP", bus);
5746                 break;
5747         case ISPASYNC_DEV_ARRIVED:
5748                 va_start(ap, cmd);
5749                 bus = va_arg(ap, int);
5750                 lp = va_arg(ap, fcportdb_t *);
5751                 va_end(ap);
5752                 fc = ISP_FC_PC(isp, bus);
5753                 lp->announced = 0;
5754                 lp->gone_timer = 0;
5755                 if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) && (lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) {
5756                         int dbidx = lp - FCPARAM(isp, bus)->portdb;
5757                         int i;
5758
5759                         for (i = 0; i < MAX_FC_TARG; i++) {
5760                                 if (i >= FL_ID && i <= SNS_ID) {
5761                                         continue;
5762                                 }
5763                                 if (FCPARAM(isp, bus)->isp_dev_map[i] == 0) {
5764                                         break;
5765                                 }
5766                         }
5767                         if (i < MAX_FC_TARG) {
5768                                 FCPARAM(isp, bus)->isp_dev_map[i] = dbidx + 1;
5769                                 lp->dev_map_idx = i + 1;
5770                         } else {
5771                                 isp_prt(isp, ISP_LOGWARN, "out of target ids");
5772                                 isp_dump_portdb(isp, bus);
5773                         }
5774                 }
5775                 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5776                 if (lp->dev_map_idx) {
5777                         tgt = lp->dev_map_idx - 1;
5778                         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);
5779                         isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
5780                         isp_make_here(isp, lp, bus, tgt);
5781                 } else {
5782                         isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "arrived", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5783                 }
5784                 break;
5785         case ISPASYNC_DEV_CHANGED:
5786                 va_start(ap, cmd);
5787                 bus = va_arg(ap, int);
5788                 lp = va_arg(ap, fcportdb_t *);
5789                 va_end(ap);
5790                 fc = ISP_FC_PC(isp, bus);
5791                 lp->announced = 0;
5792                 lp->gone_timer = 0;
5793                 if (isp_change_is_bad) {
5794                         lp->state = FC_PORTDB_STATE_NIL;
5795                         if (lp->dev_map_idx) {
5796                                 tgt = lp->dev_map_idx - 1;
5797                                 FCPARAM(isp, bus)->isp_dev_map[tgt] = 0;
5798                                 lp->dev_map_idx = 0;
5799                                 isp_prt(isp, ISP_LOGCONFIG, prom3, bus, lp->portid, tgt, "change is bad");
5800                                 isp_make_gone(isp, lp, bus, tgt);
5801                         } else {
5802                                 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5803                                 isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "changed and departed",
5804                                     (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5805                         }
5806                 } else {
5807                         lp->portid = lp->new_portid;
5808                         lp->prli_word3 = lp->new_prli_word3;
5809                         isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5810                         if (lp->dev_map_idx) {
5811                                 int t = lp->dev_map_idx - 1;
5812                                 FCPARAM(isp, bus)->isp_dev_map[t] = (lp - FCPARAM(isp, bus)->portdb) + 1;
5813                                 tgt = lp->dev_map_idx - 1;
5814                                 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "changed at", tgt,
5815                                     (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5816                                 isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
5817                         } else {
5818                                 isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "changed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5819                         }
5820                 }
5821                 break;
5822         case ISPASYNC_DEV_STAYED:
5823                 va_start(ap, cmd);
5824                 bus = va_arg(ap, int);
5825                 lp = va_arg(ap, fcportdb_t *);
5826                 va_end(ap);
5827                 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5828                 if (lp->dev_map_idx) {
5829                         fc = ISP_FC_PC(isp, bus);
5830                         tgt = lp->dev_map_idx - 1;
5831                         isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "stayed at", tgt,
5832                             (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5833                         /*
5834                          * Only issue a rescan if we've actually reported
5835                          * that this device is gone.
5836                          */
5837                         if (lp->reported_gone != 0) {
5838                                 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "rescanned at", tgt, 
5839                                     (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5840                                 isp_make_here(isp, lp, bus, tgt);
5841                         }
5842                 } else {
5843                         isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "stayed",
5844                             (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5845                 }
5846                 break;
5847         case ISPASYNC_DEV_GONE:
5848                 va_start(ap, cmd);
5849                 bus = va_arg(ap, int);
5850                 lp = va_arg(ap, fcportdb_t *);
5851                 va_end(ap);
5852                 fc = ISP_FC_PC(isp, bus);
5853                 /*
5854                  * If this has a virtual target and we haven't marked it
5855                  * that we're going to have isp_gdt tell the OS it's gone,
5856                  * set the isp_gdt timer running on it.
5857                  *
5858                  * If it isn't marked that isp_gdt is going to get rid of it,
5859                  * announce that it's gone.
5860                  *
5861                  */
5862                 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
5863                 if (lp->dev_map_idx && lp->announced == 0) {
5864                         lp->announced = 1;
5865                         lp->state = FC_PORTDB_STATE_ZOMBIE;
5866                         lp->gone_timer = ISP_FC_PC(isp, bus)->gone_device_time;
5867                         if (fc->ready && !callout_active(&fc->gdt)) {
5868                                 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);
5869                                 callout_reset(&fc->gdt, hz, isp_gdt, fc);
5870                         }
5871                         tgt = lp->dev_map_idx - 1;
5872                         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);
5873                         isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
5874                 } else if (lp->announced == 0) {
5875                         isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "departed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
5876                 }
5877                 break;
5878         case ISPASYNC_CHANGE_NOTIFY:
5879         {
5880                 char *msg;
5881                 int evt, nphdl, nlstate, reason;
5882
5883                 va_start(ap, cmd);
5884                 bus = va_arg(ap, int);
5885                 evt = va_arg(ap, int);
5886                 if (IS_24XX(isp) && evt == ISPASYNC_CHANGE_PDB) {
5887                         nphdl = va_arg(ap, int);
5888                         nlstate = va_arg(ap, int);
5889                         reason = va_arg(ap, int);
5890                 } else {
5891                         nphdl = NIL_HANDLE;
5892                         nlstate = reason = 0;
5893                 }
5894                 va_end(ap);
5895                 fc = ISP_FC_PC(isp, bus);
5896
5897                 if (evt == ISPASYNC_CHANGE_PDB) {
5898                         msg = "Chan %d Port Database Changed";
5899                 } else if (evt == ISPASYNC_CHANGE_SNS) {
5900                         msg = "Chan %d Name Server Database Changed";
5901                 } else {
5902                         msg = "Chan %d Other Change Notify";
5903                 }
5904
5905                 /*
5906                  * If the loop down timer is running, cancel it.
5907                  */
5908                 if (fc->ready && callout_active(&fc->ldt)) {
5909                         isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Stopping Loop Down Timer @ %lu", (unsigned long) time_uptime);
5910                         callout_stop(&fc->ldt);
5911                 }
5912                 isp_prt(isp, ISP_LOGINFO, msg, bus);
5913                 if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
5914                         isp_freeze_loopdown(isp, bus, msg);
5915                 }
5916                 wakeup(fc);
5917                 break;
5918         }
5919 #ifdef  ISP_TARGET_MODE
5920         case ISPASYNC_TARGET_NOTIFY:
5921         {
5922                 isp_notify_t *notify;
5923                 va_start(ap, cmd);
5924                 notify = va_arg(ap, isp_notify_t *);
5925                 va_end(ap);
5926                 switch (notify->nt_ncode) {
5927                 case NT_ABORT_TASK:
5928                 case NT_ABORT_TASK_SET:
5929                 case NT_CLEAR_ACA:
5930                 case NT_CLEAR_TASK_SET:
5931                 case NT_LUN_RESET:
5932                 case NT_TARGET_RESET:
5933                         /*
5934                          * These are task management functions.
5935                          */
5936                         isp_handle_platform_target_tmf(isp, notify);
5937                         break;
5938                 case NT_BUS_RESET:
5939                 case NT_LIP_RESET:
5940                 case NT_LINK_UP:
5941                 case NT_LINK_DOWN:
5942                         /*
5943                          * No action need be taken here.
5944                          */
5945                         break;
5946                 case NT_HBA_RESET:
5947                         isp_del_all_wwn_entries(isp, ISP_NOCHAN);
5948                         break;
5949                 case NT_GLOBAL_LOGOUT:
5950                 case NT_LOGOUT:
5951                         /*
5952                          * This is device arrival/departure notification
5953                          */
5954                         isp_handle_platform_target_notify_ack(isp, notify);
5955                         break;
5956                 case NT_ARRIVED:
5957                 {
5958                         struct ac_contract ac;
5959                         struct ac_device_changed *fc;
5960
5961                         ac.contract_number = AC_CONTRACT_DEV_CHG;
5962                         fc = (struct ac_device_changed *) ac.contract_data;
5963                         fc->wwpn = notify->nt_wwn;
5964                         fc->port = notify->nt_sid;
5965                         fc->target = notify->nt_nphdl;
5966                         fc->arrived = 1;
5967                         xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac);
5968                         break;
5969                 }
5970                 case NT_DEPARTED:
5971                 {
5972                         struct ac_contract ac;
5973                         struct ac_device_changed *fc;
5974
5975                         ac.contract_number = AC_CONTRACT_DEV_CHG;
5976                         fc = (struct ac_device_changed *) ac.contract_data;
5977                         fc->wwpn = notify->nt_wwn;
5978                         fc->port = notify->nt_sid;
5979                         fc->target = notify->nt_nphdl;
5980                         fc->arrived = 0;
5981                         xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac);
5982                         break;
5983                 }
5984                 default:
5985                         isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode);
5986                         isp_handle_platform_target_notify_ack(isp, notify);
5987                         break;
5988                 }
5989                 break;
5990         }
5991         case ISPASYNC_TARGET_NOTIFY_ACK:
5992         {
5993                 void *inot;
5994                 va_start(ap, cmd);
5995                 inot = va_arg(ap, void *);
5996                 va_end(ap);
5997                 if (isp_notify_ack(isp, inot)) {
5998                         isp_tna_t *tp = malloc(sizeof (*tp), M_DEVBUF, M_NOWAIT);
5999                         if (tp) {
6000                                 tp->isp = isp;
6001                                 if (inot) {
6002                                         memcpy(tp->data, inot, sizeof (tp->data));
6003                                         tp->not = tp->data;
6004                                 } else {
6005                                         tp->not = NULL;
6006                                 }
6007                                 callout_init_mtx(&tp->timer, &isp->isp_lock, 0);
6008                                 callout_reset(&tp->timer, 5,
6009                                     isp_refire_notify_ack, tp);
6010                         } else {
6011                                 isp_prt(isp, ISP_LOGERR, "you lose- cannot allocate a notify refire");
6012                         }
6013                 }
6014                 break;
6015         }
6016         case ISPASYNC_TARGET_ACTION:
6017         {
6018                 isphdr_t *hp;
6019
6020                 va_start(ap, cmd);
6021                 hp = va_arg(ap, isphdr_t *);
6022                 va_end(ap);
6023                 switch (hp->rqs_entry_type) {
6024                 default:
6025                         isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x", __func__, hp->rqs_entry_type);
6026                         break;
6027                 case RQSTYPE_NOTIFY:
6028                         if (IS_SCSI(isp)) {
6029                                 isp_handle_platform_notify_scsi(isp, (in_entry_t *) hp);
6030                         } else if (IS_24XX(isp)) {
6031                                 isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp);
6032                         } else {
6033                                 isp_handle_platform_notify_fc(isp, (in_fcentry_t *) hp);
6034                         }
6035                         break;
6036                 case RQSTYPE_ATIO:
6037                         if (IS_24XX(isp)) {
6038                                 isp_handle_platform_atio7(isp, (at7_entry_t *) hp);
6039                         } else {
6040                                 isp_handle_platform_atio(isp, (at_entry_t *) hp);
6041                         }
6042                         break;
6043                 case RQSTYPE_ATIO2:
6044                         isp_handle_platform_atio2(isp, (at2_entry_t *) hp);
6045                         break;
6046                 case RQSTYPE_CTIO7:
6047                 case RQSTYPE_CTIO3:
6048                 case RQSTYPE_CTIO2:
6049                 case RQSTYPE_CTIO:
6050                         isp_handle_platform_ctio(isp, hp);
6051                         break;
6052                 case RQSTYPE_ABTS_RCVD:
6053                 {
6054                         abts_t *abts = (abts_t *)hp;
6055                         isp_notify_t notify, *nt = &notify;
6056                         tstate_t *tptr;
6057                         fcportdb_t *lp;
6058                         uint16_t chan;
6059                         uint32_t sid, did;
6060
6061                         did = (abts->abts_did_hi << 16) | abts->abts_did_lo;
6062                         sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo;
6063                         ISP_MEMZERO(nt, sizeof (isp_notify_t));
6064
6065                         nt->nt_hba = isp;
6066                         nt->nt_did = did;
6067                         nt->nt_nphdl = abts->abts_nphdl;
6068                         nt->nt_sid = sid;
6069                         isp_find_chan_by_did(isp, did, &chan);
6070                         if (chan == ISP_NOCHAN) {
6071                                 nt->nt_tgt = TGT_ANY;
6072                         } else {
6073                                 nt->nt_tgt = FCPARAM(isp, chan)->isp_wwpn;
6074                                 if (isp_find_pdb_by_loopid(isp, chan, abts->abts_nphdl, &lp)) {
6075                                         nt->nt_wwn = lp->port_wwn;
6076                                 } else {
6077                                         nt->nt_wwn = INI_ANY;
6078                                 }
6079                         }
6080                         /*
6081                          * Try hard to find the lun for this command.
6082                          */
6083                         tptr = get_lun_statep_from_tag(isp, chan, abts->abts_rxid_task);
6084                         if (tptr) {
6085                                 nt->nt_lun = tptr->ts_lun;
6086                                 rls_lun_statep(isp, tptr);
6087                         } else {
6088                                 nt->nt_lun = LUN_ANY;
6089                         }
6090                         nt->nt_need_ack = 1;
6091                         nt->nt_tagval = abts->abts_rxid_task;
6092                         nt->nt_tagval |= (((uint64_t) abts->abts_rxid_abts) << 32);
6093                         if (abts->abts_rxid_task == ISP24XX_NO_TASK) {
6094                                 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)",
6095                                     abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rx_id, abts->abts_ox_id);
6096                         } else {
6097                                 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)",
6098                                     abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rxid_task, abts->abts_rx_id, abts->abts_ox_id);
6099                         }
6100                         nt->nt_channel = chan;
6101                         nt->nt_ncode = NT_ABORT_TASK;
6102                         nt->nt_lreserved = hp;
6103                         isp_handle_platform_target_tmf(isp, nt);
6104                         break;
6105                 }
6106                 case RQSTYPE_ENABLE_LUN:
6107                 case RQSTYPE_MODIFY_LUN:
6108                         isp_ledone(isp, (lun_entry_t *) hp);
6109                         break;
6110                 }
6111                 break;
6112         }
6113 #endif
6114         case ISPASYNC_FW_CRASH:
6115         {
6116                 uint16_t mbox1, mbox6;
6117                 mbox1 = ISP_READ(isp, OUTMAILBOX1);
6118                 if (IS_DUALBUS(isp)) { 
6119                         mbox6 = ISP_READ(isp, OUTMAILBOX6);
6120                 } else {
6121                         mbox6 = 0;
6122                 }
6123                 isp_prt(isp, ISP_LOGERR, "Internal Firmware Error on bus %d @ RISC Address 0x%x", mbox6, mbox1);
6124                 mbox1 = isp->isp_osinfo.mbox_sleep_ok;
6125                 isp->isp_osinfo.mbox_sleep_ok = 0;
6126                 isp_reinit(isp, 1);
6127                 isp->isp_osinfo.mbox_sleep_ok = mbox1;
6128                 isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
6129                 break;
6130         }
6131         default:
6132                 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
6133                 break;
6134         }
6135 }
6136
6137
6138 /*
6139  * Locks are held before coming here.
6140  */
6141 void
6142 isp_uninit(ispsoftc_t *isp)
6143 {
6144         if (IS_24XX(isp)) {
6145                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
6146         } else {
6147                 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
6148         }
6149         ISP_DISABLE_INTS(isp);
6150 }
6151
6152 /*
6153  * When we want to get the 'default' WWNs (when lacking NVRAM), we pick them
6154  * up from our platform default (defww{p|n}n) and morph them based upon
6155  * channel.
6156  * 
6157  * When we want to get the 'active' WWNs, we get NVRAM WWNs and then morph them
6158  * based upon channel.
6159  */
6160
6161 uint64_t
6162 isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn)
6163 {
6164         uint64_t seed;
6165         struct isp_fc *fc = ISP_FC_PC(isp, chan);
6166
6167         /*
6168          * If we're asking for a active WWN, the default overrides get
6169          * returned, otherwise the NVRAM value is picked.
6170          * 
6171          * If we're asking for a default WWN, we just pick the default override.
6172          */
6173         if (isactive) {
6174                 seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
6175                 if (seed) {
6176                         return (seed);
6177                 }
6178                 seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram : FCPARAM(isp, chan)->isp_wwpn_nvram;
6179                 if (seed) {
6180                         return (seed);
6181                 }
6182                 return (0x400000007F000009ull);
6183         }
6184
6185         seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
6186
6187         /*
6188          * For channel zero just return what we have. For either ACTIVE or
6189          * DEFAULT cases, we depend on default override of NVRAM values for
6190          * channel zero.
6191          */
6192         if (chan == 0) {
6193                 return (seed);
6194         }
6195
6196         /*
6197          * For other channels, we are doing one of three things:
6198          * 
6199          * 1. If what we have now is non-zero, return it. Otherwise we morph
6200          * values from channel 0. 2. If we're here for a WWPN we synthesize
6201          * it if Channel 0's wwpn has a type 2 NAA. 3. If we're here for a
6202          * WWNN we synthesize it if Channel 0's wwnn has a type 2 NAA.
6203          */
6204
6205         if (seed) {
6206                 return (seed);
6207         }
6208         seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn : ISP_FC_PC(isp, 0)->def_wwpn;
6209         if (seed == 0)
6210                 seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram : FCPARAM(isp, 0)->isp_wwpn_nvram;
6211
6212         if (((seed >> 60) & 0xf) == 2) {
6213                 /*
6214                  * The type 2 NAA fields for QLogic cards appear be laid out
6215                  * thusly:
6216                  * 
6217                  * bits 63..60 NAA == 2 bits 59..57 unused/zero bit 56
6218                  * port (1) or node (0) WWN distinguishor bit 48
6219                  * physical port on dual-port chips (23XX/24XX)
6220                  * 
6221                  * This is somewhat nutty, particularly since bit 48 is
6222                  * irrelevant as they assign separate serial numbers to
6223                  * different physical ports anyway.
6224                  * 
6225                  * We'll stick our channel number plus one first into bits
6226                  * 57..59 and thence into bits 52..55 which allows for 8 bits
6227                  * of channel which is comfortably more than our maximum
6228                  * (126) now.
6229                  */
6230                 seed &= ~0x0FF0000000000000ULL;
6231                 if (iswwnn == 0) {
6232                         seed |= ((uint64_t) (chan + 1) & 0xf) << 56;
6233                         seed |= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52;
6234                 }
6235         } else {
6236                 seed = 0;
6237         }
6238         return (seed);
6239 }
6240
6241 void
6242 isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
6243 {
6244         int loc;
6245         char lbuf[200];
6246         va_list ap;
6247
6248         if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
6249                 return;
6250         }
6251         snprintf(lbuf, sizeof (lbuf), "%s: ", device_get_nameunit(isp->isp_dev));
6252         loc = strlen(lbuf);
6253         va_start(ap, fmt);
6254         vsnprintf(&lbuf[loc], sizeof (lbuf) - loc - 1, fmt, ap); 
6255         va_end(ap);
6256         printf("%s\n", lbuf);
6257 }
6258
6259 void
6260 isp_xs_prt(ispsoftc_t *isp, XS_T *xs, int level, const char *fmt, ...)
6261 {
6262         va_list ap;
6263         if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
6264                 return;
6265         }
6266         xpt_print_path(xs->ccb_h.path);
6267         va_start(ap, fmt);
6268         vprintf(fmt, ap);
6269         va_end(ap);
6270         printf("\n");
6271 }
6272
6273 uint64_t
6274 isp_nanotime_sub(struct timespec *b, struct timespec *a)
6275 {
6276         uint64_t elapsed;
6277         struct timespec x = *b;
6278         timespecsub(&x, a);
6279         elapsed = GET_NANOSEC(&x);
6280         if (elapsed == 0)
6281                 elapsed++;
6282         return (elapsed);
6283 }
6284
6285 int
6286 isp_mbox_acquire(ispsoftc_t *isp)
6287 {
6288         if (isp->isp_osinfo.mboxbsy) {
6289                 return (1);
6290         } else {
6291                 isp->isp_osinfo.mboxcmd_done = 0;
6292                 isp->isp_osinfo.mboxbsy = 1;
6293                 return (0);
6294         }
6295 }
6296
6297 void
6298 isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
6299 {
6300         unsigned int usecs = mbp->timeout;
6301         unsigned int max, olim, ilim;
6302
6303         if (usecs == 0) {
6304                 usecs = MBCMD_DEFAULT_TIMEOUT;
6305         }
6306         max = isp->isp_mbxwrk0 + 1;
6307
6308         if (isp->isp_osinfo.mbox_sleep_ok) {
6309                 unsigned int ms = (usecs + 999) / 1000;
6310
6311                 isp->isp_osinfo.mbox_sleep_ok = 0;
6312                 isp->isp_osinfo.mbox_sleeping = 1;
6313                 for (olim = 0; olim < max; olim++) {
6314                         msleep(&isp->isp_mbxworkp, &isp->isp_osinfo.lock, PRIBIO, "ispmbx_sleep", isp_mstohz(ms));
6315                         if (isp->isp_osinfo.mboxcmd_done) {
6316                                 break;
6317                         }
6318                 }
6319                 isp->isp_osinfo.mbox_sleep_ok = 1;
6320                 isp->isp_osinfo.mbox_sleeping = 0;
6321         } else {
6322                 for (olim = 0; olim < max; olim++) {
6323                         for (ilim = 0; ilim < usecs; ilim += 100) {
6324                                 uint32_t isr;
6325                                 uint16_t sema, mbox;
6326                                 if (isp->isp_osinfo.mboxcmd_done) {
6327                                         break;
6328                                 }
6329                                 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
6330                                         isp_intr(isp, isr, sema, mbox);
6331                                         if (isp->isp_osinfo.mboxcmd_done) {
6332                                                 break;
6333                                         }
6334                                 }
6335                                 ISP_DELAY(100);
6336                         }
6337                         if (isp->isp_osinfo.mboxcmd_done) {
6338                                 break;
6339                         }
6340                 }
6341         }
6342         if (isp->isp_osinfo.mboxcmd_done == 0) {
6343                 isp_prt(isp, ISP_LOGWARN, "%s Mailbox Command (0x%x) Timeout (%uus) (started @ %s:%d)",
6344                     isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled", isp->isp_lastmbxcmd, usecs, mbp->func, mbp->lineno);
6345                 mbp->param[0] = MBOX_TIMEOUT;
6346                 isp->isp_osinfo.mboxcmd_done = 1;
6347         }
6348 }
6349
6350 void
6351 isp_mbox_notify_done(ispsoftc_t *isp)
6352 {
6353         if (isp->isp_osinfo.mbox_sleeping) {
6354                 wakeup(&isp->isp_mbxworkp);
6355         }
6356         isp->isp_osinfo.mboxcmd_done = 1;
6357 }
6358
6359 void
6360 isp_mbox_release(ispsoftc_t *isp)
6361 {
6362         isp->isp_osinfo.mboxbsy = 0;
6363 }
6364
6365 int
6366 isp_fc_scratch_acquire(ispsoftc_t *isp, int chan)
6367 {
6368         int ret = 0;
6369         if (isp->isp_osinfo.pc.fc[chan].fcbsy) {
6370                 ret = -1;
6371         } else {
6372                 isp->isp_osinfo.pc.fc[chan].fcbsy = 1;
6373         }
6374         return (ret);
6375 }
6376
6377 int
6378 isp_mstohz(int ms)
6379 {
6380         int hz;
6381         struct timeval t;
6382         t.tv_sec = ms / 1000;
6383         t.tv_usec = (ms % 1000) * 1000;
6384         hz = tvtohz(&t);
6385         if (hz < 0) {
6386                 hz = 0x7fffffff;
6387         }
6388         if (hz == 0) {
6389                 hz = 1;
6390         }
6391         return (hz);
6392 }
6393
6394 void
6395 isp_platform_intr(void *arg)
6396 {
6397         ispsoftc_t *isp = arg;
6398         uint32_t isr;
6399         uint16_t sema, mbox;
6400
6401         ISP_LOCK(isp);
6402         isp->isp_intcnt++;
6403         if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
6404                 isp->isp_intbogus++;
6405         } else {
6406                 isp_intr(isp, isr, sema, mbox);
6407         }
6408         ISP_UNLOCK(isp);
6409 }
6410
6411 void
6412 isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl)
6413 {
6414         if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
6415                 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTREAD);
6416         } else {
6417                 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTWRITE);
6418         }
6419         bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap);
6420 }
6421
6422 /*
6423  * Reset the command reference number for all LUNs on a specific target
6424  * (needed when a target arrives again) or for all targets on a port
6425  * (needed for events like a LIP).
6426  */
6427 void
6428 isp_fcp_reset_crn(struct isp_fc *fc, uint32_t tgt, int tgt_set)
6429 {
6430         int i;
6431         struct isp_nexus *nxp;
6432
6433         if (tgt_set == 0)
6434                 isp_prt(fc->isp, ISP_LOG_SANCFG, "resetting CRN on all targets");
6435         else
6436                 isp_prt(fc->isp, ISP_LOG_SANCFG, "resetting CRN target %u", tgt);
6437
6438         for (i = 0; i < NEXUS_HASH_WIDTH; i++) {
6439                 nxp = fc->nexus_hash[i];
6440                 while (nxp) {
6441                         if ((tgt_set != 0) && (tgt == nxp->tgt))
6442                                 nxp->crnseed = 0;
6443
6444                         nxp = nxp->next;
6445                 }
6446         }
6447 }
6448
6449 int
6450 isp_fcp_next_crn(ispsoftc_t *isp, uint8_t *crnp, XS_T *cmd)
6451 {
6452         uint32_t chan, tgt, lun;
6453         struct isp_fc *fc;
6454         struct isp_nexus *nxp;
6455         int idx;
6456
6457         if (isp->isp_type < ISP_HA_FC_2300)
6458                 return (0);
6459
6460         chan = XS_CHANNEL(cmd);
6461         tgt = XS_TGT(cmd);
6462         lun = XS_LUN(cmd);
6463         fc = &isp->isp_osinfo.pc.fc[chan];
6464         idx = NEXUS_HASH(tgt, lun);
6465         nxp = fc->nexus_hash[idx];
6466
6467         while (nxp) {
6468                 if (nxp->tgt == tgt && nxp->lun == lun)
6469                         break;
6470                 nxp = nxp->next;
6471         }
6472         if (nxp == NULL) {
6473                 nxp = fc->nexus_free_list;
6474                 if (nxp == NULL) {
6475                         nxp = malloc(sizeof (struct isp_nexus), M_DEVBUF, M_ZERO|M_NOWAIT);
6476                         if (nxp == NULL) {
6477                                 return (-1);
6478                         }
6479                 } else {
6480                         fc->nexus_free_list = nxp->next;
6481                 }
6482                 nxp->tgt = tgt;
6483                 nxp->lun = lun;
6484                 nxp->next = fc->nexus_hash[idx];
6485                 fc->nexus_hash[idx] = nxp;
6486         }
6487         if (nxp) {
6488                 if (nxp->crnseed == 0)
6489                         nxp->crnseed = 1;
6490                 if (cmd)
6491                         PISP_PCMD(cmd)->crn = nxp->crnseed;
6492                 *crnp = nxp->crnseed++;
6493                 return (0);
6494         }
6495         return (-1);
6496 }
6497
6498 /*
6499  * We enter with the lock held
6500  */
6501 void
6502 isp_timer(void *arg)
6503 {
6504         ispsoftc_t *isp = arg;
6505 #ifdef  ISP_TARGET_MODE
6506         isp_tmcmd_restart(isp);
6507 #endif
6508         callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp);
6509 }
6510
6511 isp_ecmd_t *
6512 isp_get_ecmd(ispsoftc_t *isp)
6513 {
6514         isp_ecmd_t *ecmd = isp->isp_osinfo.ecmd_free;
6515         if (ecmd) {
6516                 isp->isp_osinfo.ecmd_free = ecmd->next;
6517         }
6518         return (ecmd);
6519 }
6520
6521 void
6522 isp_put_ecmd(ispsoftc_t *isp, isp_ecmd_t *ecmd)
6523 {
6524         ecmd->next = isp->isp_osinfo.ecmd_free;
6525         isp->isp_osinfo.ecmd_free = ecmd;
6526 }