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