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