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