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