]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/isp/isp_freebsd.c
This commit was generated by cvs2svn to compensate for changes in r162503,
[FreeBSD/FreeBSD.git] / sys / dev / isp / isp_freebsd.c
1 /*-
2  *
3  * Copyright (c) 1997-2006 by Matthew Jacob
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice immediately at the beginning of the file, without modification,
11  *    this list of conditions, and the following disclaimer.
12  * 2. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 /*
29  * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
30  */
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 #include <dev/isp/isp_freebsd.h>
34 #include <sys/unistd.h>
35 #include <sys/kthread.h>
36 #include <machine/stdarg.h>     /* for use by isp_prt below */
37 #include <sys/conf.h>
38 #include <sys/module.h>
39 #include <sys/ioccom.h>
40 #include <dev/isp/isp_ioctl.h>
41
42
43 MODULE_VERSION(isp, 1);
44 MODULE_DEPEND(isp, cam, 1, 1, 1);
45 int isp_announced = 0;
46
47 static d_ioctl_t ispioctl;
48 static void isp_intr_enable(void *);
49 static void isp_cam_async(void *, uint32_t, struct cam_path *, void *);
50 static void isp_poll(struct cam_sim *);
51 static timeout_t isp_watchdog;
52 static void isp_kthread(void *);
53 static void isp_action(struct cam_sim *, union ccb *);
54
55 #if __FreeBSD_version < 700000
56 ispfwfunc *isp_get_firmware_p = NULL;
57 #endif
58
59 #if __FreeBSD_version < 500000  
60 #define ISP_CDEV_MAJOR  248
61 static struct cdevsw isp_cdevsw = {
62         /* open */      nullopen,
63         /* close */     nullclose,
64         /* read */      noread,
65         /* write */     nowrite,
66         /* ioctl */     ispioctl,
67         /* poll */      nopoll,
68         /* mmap */      nommap,
69         /* strategy */  nostrategy,
70         /* name */      "isp",
71         /* maj */       ISP_CDEV_MAJOR,
72         /* dump */      nodump,
73         /* psize */     nopsize,
74         /* flags */     D_TAPE,
75 };
76 #else
77 static struct cdevsw isp_cdevsw = {
78         .d_version =    D_VERSION,
79         .d_flags =      D_NEEDGIANT,
80         .d_ioctl =      ispioctl,
81         .d_name =       "isp",
82 };
83 #endif
84
85 static ispsoftc_t *isplist = NULL;
86
87 void
88 isp_attach(ispsoftc_t *isp)
89 {
90         int primary, secondary;
91         struct ccb_setasync csa;
92         struct cam_devq *devq;
93         struct cam_sim *sim;
94         struct cam_path *path;
95
96         /*
97          * Establish (in case of 12X0) which bus is the primary.
98          */
99
100         primary = 0;
101         secondary = 1;
102
103         /*
104          * Create the device queue for our SIM(s).
105          */
106         devq = cam_simq_alloc(isp->isp_maxcmds);
107         if (devq == NULL) {
108                 return;
109         }
110
111         /*
112          * Construct our SIM entry.
113          */
114         ISPLOCK_2_CAMLOCK(isp);
115         sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
116             device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
117         if (sim == NULL) {
118                 cam_simq_free(devq);
119                 CAMLOCK_2_ISPLOCK(isp);
120                 return;
121         }
122         CAMLOCK_2_ISPLOCK(isp);
123
124         isp->isp_osinfo.ehook.ich_func = isp_intr_enable;
125         isp->isp_osinfo.ehook.ich_arg = isp;
126         ISPLOCK_2_CAMLOCK(isp);
127         if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) {
128                 cam_sim_free(sim, TRUE);
129                 CAMLOCK_2_ISPLOCK(isp);
130                 isp_prt(isp, ISP_LOGERR,
131                     "could not establish interrupt enable hook");
132                 return;
133         }
134
135         if (xpt_bus_register(sim, primary) != CAM_SUCCESS) {
136                 cam_sim_free(sim, TRUE);
137                 CAMLOCK_2_ISPLOCK(isp);
138                 return;
139         }
140
141         if (xpt_create_path(&path, NULL, cam_sim_path(sim),
142             CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
143                 xpt_bus_deregister(cam_sim_path(sim));
144                 cam_sim_free(sim, TRUE);
145                 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
146                 CAMLOCK_2_ISPLOCK(isp);
147                 return;
148         }
149
150         xpt_setup_ccb(&csa.ccb_h, path, 5);
151         csa.ccb_h.func_code = XPT_SASYNC_CB;
152         csa.event_enable = AC_LOST_DEVICE;
153         csa.callback = isp_cam_async;
154         csa.callback_arg = sim;
155         xpt_action((union ccb *)&csa);
156         CAMLOCK_2_ISPLOCK(isp);
157         isp->isp_sim = sim;
158         isp->isp_path = path;
159         /*
160          * Create a kernel thread for fibre channel instances. We
161          * don't have dual channel FC cards.
162          */
163         if (IS_FC(isp)) {
164                 ISPLOCK_2_CAMLOCK(isp);
165 #if __FreeBSD_version >= 500000  
166                 /* XXX: LOCK VIOLATION */
167                 cv_init(&isp->isp_osinfo.kthread_cv, "isp_kthread_cv");
168                 if (kthread_create(isp_kthread, isp, &isp->isp_osinfo.kproc,
169                     RFHIGHPID, 0, "%s: fc_thrd",
170                     device_get_nameunit(isp->isp_dev)))
171 #else
172                 if (kthread_create(isp_kthread, isp, &isp->isp_osinfo.kproc,
173                     "%s: fc_thrd", device_get_nameunit(isp->isp_dev)))
174 #endif
175                 {
176                         xpt_bus_deregister(cam_sim_path(sim));
177                         cam_sim_free(sim, TRUE);
178                         config_intrhook_disestablish(&isp->isp_osinfo.ehook);
179                         CAMLOCK_2_ISPLOCK(isp);
180                         isp_prt(isp, ISP_LOGERR, "could not create kthread");
181                         return;
182                 }
183                 CAMLOCK_2_ISPLOCK(isp);
184         }
185
186
187         /*
188          * If we have a second channel, construct SIM entry for that.
189          */
190         if (IS_DUALBUS(isp)) {
191                 ISPLOCK_2_CAMLOCK(isp);
192                 sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
193                     device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
194                 if (sim == NULL) {
195                         xpt_bus_deregister(cam_sim_path(isp->isp_sim));
196                         xpt_free_path(isp->isp_path);
197                         cam_simq_free(devq);
198                         config_intrhook_disestablish(&isp->isp_osinfo.ehook);
199                         return;
200                 }
201                 if (xpt_bus_register(sim, secondary) != CAM_SUCCESS) {
202                         xpt_bus_deregister(cam_sim_path(isp->isp_sim));
203                         xpt_free_path(isp->isp_path);
204                         cam_sim_free(sim, TRUE);
205                         config_intrhook_disestablish(&isp->isp_osinfo.ehook);
206                         CAMLOCK_2_ISPLOCK(isp);
207                         return;
208                 }
209
210                 if (xpt_create_path(&path, NULL, cam_sim_path(sim),
211                     CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
212                         xpt_bus_deregister(cam_sim_path(isp->isp_sim));
213                         xpt_free_path(isp->isp_path);
214                         xpt_bus_deregister(cam_sim_path(sim));
215                         cam_sim_free(sim, TRUE);
216                         config_intrhook_disestablish(&isp->isp_osinfo.ehook);
217                         CAMLOCK_2_ISPLOCK(isp);
218                         return;
219                 }
220
221                 xpt_setup_ccb(&csa.ccb_h, path, 5);
222                 csa.ccb_h.func_code = XPT_SASYNC_CB;
223                 csa.event_enable = AC_LOST_DEVICE;
224                 csa.callback = isp_cam_async;
225                 csa.callback_arg = sim;
226                 xpt_action((union ccb *)&csa);
227                 CAMLOCK_2_ISPLOCK(isp);
228                 isp->isp_sim2 = sim;
229                 isp->isp_path2 = path;
230         }
231
232         /*
233          * Create device nodes
234          */
235         (void) make_dev(&isp_cdevsw, device_get_unit(isp->isp_dev), UID_ROOT,
236             GID_OPERATOR, 0600, "%s", device_get_nameunit(isp->isp_dev));
237
238         if (isp->isp_role != ISP_ROLE_NONE) {
239                 isp->isp_state = ISP_RUNSTATE;
240                 ENABLE_INTS(isp);
241         }
242         if (isplist == NULL) {
243                 isplist = isp;
244         } else {
245                 ispsoftc_t *tmp = isplist;
246                 while (tmp->isp_osinfo.next) {
247                         tmp = tmp->isp_osinfo.next;
248                 }
249                 tmp->isp_osinfo.next = isp;
250         }
251
252 }
253
254 static __inline void
255 isp_freeze_loopdown(ispsoftc_t *isp, char *msg)
256 {
257         if (isp->isp_osinfo.simqfrozen == 0) {
258                 isp_prt(isp, ISP_LOGDEBUG0, "%s: freeze simq (loopdown)", msg);
259                 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
260                 ISPLOCK_2_CAMLOCK(isp);
261                 xpt_freeze_simq(isp->isp_sim, 1);
262                 CAMLOCK_2_ISPLOCK(isp);
263         } else {
264                 isp_prt(isp, ISP_LOGDEBUG0, "%s: mark frozen (loopdown)", msg);
265                 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
266         }
267 }
268
269
270 #if __FreeBSD_version < 500000  
271 #define _DEV    dev_t
272 #define _IOP    struct proc
273 #else
274 #define _IOP    struct thread
275 #define _DEV    struct cdev *
276 #endif
277
278 static int
279 ispioctl(_DEV dev, u_long c, caddr_t addr, int flags, _IOP *td)
280 {
281         ispsoftc_t *isp;
282         int nr, retval = ENOTTY;
283
284         isp = isplist;
285         while (isp) {
286                 if (minor(dev) == device_get_unit(isp->isp_dev)) {
287                         break;
288                 }
289                 isp = isp->isp_osinfo.next;
290         }
291         if (isp == NULL)
292                 return (ENXIO);
293         
294         switch (c) {
295 #ifdef  ISP_FW_CRASH_DUMP
296         case ISP_GET_FW_CRASH_DUMP:
297                 if (IS_FC(isp)) {
298                         uint16_t *ptr = FCPARAM(isp)->isp_dump_data;
299                         size_t sz;
300
301                         retval = 0;
302                         if (IS_2200(isp)) {
303                                 sz = QLA2200_RISC_IMAGE_DUMP_SIZE;
304                         } else {
305                                 sz = QLA2300_RISC_IMAGE_DUMP_SIZE;
306                         }
307                         ISP_LOCK(isp);
308                         if (ptr && *ptr) {
309                                 void *uaddr = *((void **) addr);
310                                 if (copyout(ptr, uaddr, sz)) {
311                                         retval = EFAULT;
312                                 } else {
313                                         *ptr = 0;
314                                 }
315                         } else {
316                                 retval = ENXIO;
317                         }
318                         ISP_UNLOCK(isp);
319                 }
320                 break;
321         case ISP_FORCE_CRASH_DUMP:
322                 if (IS_FC(isp)) {
323                         ISP_LOCK(isp);
324                         isp_freeze_loopdown(isp,
325                             "ispioctl(ISP_FORCE_CRASH_DUMP)");
326                         isp_fw_dump(isp);
327                         isp_reinit(isp);
328                         ISP_UNLOCK(isp);
329                         retval = 0;
330                 }
331                 break;
332 #endif
333         case ISP_SDBLEV:
334         {
335                 int olddblev = isp->isp_dblev;
336                 isp->isp_dblev = *(int *)addr;
337                 *(int *)addr = olddblev;
338                 retval = 0;
339                 break;
340         }
341         case ISP_GETROLE:
342                 *(int *)addr = isp->isp_role;
343                 retval = 0;
344                 break;
345         case ISP_SETROLE:
346                 nr = *(int *)addr;
347                 if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
348                         retval = EINVAL;
349                         break;
350                 }
351                 *(int *)addr = isp->isp_role;
352                 isp->isp_role = nr;
353                 /* FALLTHROUGH */
354         case ISP_RESETHBA:
355                 ISP_LOCK(isp);
356                 isp_reinit(isp);
357                 ISP_UNLOCK(isp);
358                 retval = 0;
359                 break;
360         case ISP_RESCAN:
361                 if (IS_FC(isp)) {
362                         ISP_LOCK(isp);
363                         if (isp_fc_runstate(isp, 5 * 1000000)) {
364                                 retval = EIO;
365                         } else {
366                                 retval = 0;
367                         }
368                         ISP_UNLOCK(isp);
369                 }
370                 break;
371         case ISP_FC_LIP:
372                 if (IS_FC(isp)) {
373                         ISP_LOCK(isp);
374                         if (isp_control(isp, ISPCTL_SEND_LIP, 0)) {
375                                 retval = EIO;
376                         } else {
377                                 retval = 0;
378                         }
379                         ISP_UNLOCK(isp);
380                 }
381                 break;
382         case ISP_FC_GETDINFO:
383         {
384                 struct isp_fc_device *ifc = (struct isp_fc_device *) addr;
385                 struct lportdb *lp;
386
387                 if (IS_SCSI(isp)) {
388                         break;
389                 }
390                 if (ifc->loopid < 0 || ifc->loopid >= MAX_FC_TARG) {
391                         retval = EINVAL;
392                         break;
393                 }
394                 ISP_LOCK(isp);
395                 lp = &FCPARAM(isp)->portdb[ifc->loopid];
396                 if (lp->valid) {
397                         ifc->role = lp->roles;
398                         ifc->loopid = lp->loopid;
399                         ifc->portid = lp->portid;
400                         ifc->node_wwn = lp->node_wwn;
401                         ifc->port_wwn = lp->port_wwn;
402                         retval = 0;
403                 } else {
404                         retval = ENODEV;
405                 }
406                 ISP_UNLOCK(isp);
407                 break;
408         }
409         case ISP_GET_STATS:
410         {
411                 isp_stats_t *sp = (isp_stats_t *) addr;
412
413                 MEMZERO(sp, sizeof (*sp));
414                 sp->isp_stat_version = ISP_STATS_VERSION;
415                 sp->isp_type = isp->isp_type;
416                 sp->isp_revision = isp->isp_revision;
417                 ISP_LOCK(isp);
418                 sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt;
419                 sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
420                 sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
421                 sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;
422                 sp->isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt;
423                 sp->isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt;
424                 sp->isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater;
425                 sp->isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater;
426                 ISP_UNLOCK(isp);
427                 retval = 0;
428                 break;
429         }
430         case ISP_CLR_STATS:
431                 ISP_LOCK(isp);
432                 isp->isp_intcnt = 0;
433                 isp->isp_intbogus = 0;
434                 isp->isp_intmboxc = 0;
435                 isp->isp_intoasync = 0;
436                 isp->isp_rsltccmplt = 0;
437                 isp->isp_fphccmplt = 0;
438                 isp->isp_rscchiwater = 0;
439                 isp->isp_fpcchiwater = 0;
440                 ISP_UNLOCK(isp);
441                 retval = 0;
442                 break;
443         case ISP_FC_GETHINFO:
444         {
445                 struct isp_hba_device *hba = (struct isp_hba_device *) addr;
446                 MEMZERO(hba, sizeof (*hba));
447
448                 hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev);
449                 hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev);
450                 hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev);
451                 if (IS_FC(isp)) {
452                         hba->fc_speed = FCPARAM(isp)->isp_gbspeed;
453                         hba->fc_scsi_supported = 1;
454                         hba->fc_topology = FCPARAM(isp)->isp_topo + 1;
455                         hba->fc_loopid = FCPARAM(isp)->isp_loopid;
456                         hba->nvram_node_wwn = FCPARAM(isp)->isp_nodewwn;
457                         hba->nvram_port_wwn = FCPARAM(isp)->isp_portwwn;
458                         hba->active_node_wwn = ISP_NODEWWN(isp);
459                         hba->active_port_wwn = ISP_PORTWWN(isp);
460                 }
461                 retval = 0;
462                 break;
463         }
464         case ISP_GET_FC_PARAM:
465         {
466                 struct isp_fc_param *f = (struct isp_fc_param *) addr;
467
468                 if (IS_SCSI(isp)) {
469                         break;
470                 }
471                 f->parameter = 0;
472                 if (strcmp(f->param_name, "framelength") == 0) {
473                         f->parameter = FCPARAM(isp)->isp_maxfrmlen;
474                         retval = 0;
475                         break;
476                 }
477                 if (strcmp(f->param_name, "exec_throttle") == 0) {
478                         f->parameter = FCPARAM(isp)->isp_execthrottle;
479                         retval = 0;
480                         break;
481                 }
482                 if (strcmp(f->param_name, "fullduplex") == 0) {
483                         if (FCPARAM(isp)->isp_fwoptions & ICBOPT_FULL_DUPLEX)
484                                 f->parameter = 1;
485                         retval = 0;
486                         break;
487                 }
488                 if (strcmp(f->param_name, "loopid") == 0) {
489                         f->parameter = FCPARAM(isp)->isp_loopid;
490                         retval = 0;
491                         break;
492                 }
493                 retval = EINVAL;
494                 break;
495         }
496         case ISP_SET_FC_PARAM:
497         {
498                 struct isp_fc_param *f = (struct isp_fc_param *) addr;
499                 uint32_t param = f->parameter;
500
501                 if (IS_SCSI(isp)) {
502                         break;
503                 }
504                 f->parameter = 0;
505                 if (strcmp(f->param_name, "framelength") == 0) {
506                         if (param != 512 && param != 1024 && param != 1024) {
507                                 retval = EINVAL;
508                                 break;
509                         }
510                         FCPARAM(isp)->isp_maxfrmlen = param;
511                         retval = 0;
512                         break;
513                 }
514                 if (strcmp(f->param_name, "exec_throttle") == 0) {
515                         if (param < 16 || param > 255) {
516                                 retval = EINVAL;
517                                 break;
518                         }
519                         FCPARAM(isp)->isp_execthrottle = param;
520                         retval = 0;
521                         break;
522                 }
523                 if (strcmp(f->param_name, "fullduplex") == 0) {
524                         if (param != 0 && param != 1) {
525                                 retval = EINVAL;
526                                 break;
527                         }
528                         if (param) {
529                                 FCPARAM(isp)->isp_fwoptions |=
530                                     ICBOPT_FULL_DUPLEX;
531                         } else {
532                                 FCPARAM(isp)->isp_fwoptions &=
533                                     ~ICBOPT_FULL_DUPLEX;
534                         }
535                         retval = 0;
536                         break;
537                 }
538                 if (strcmp(f->param_name, "loopid") == 0) {
539                         if (param < 0 || param > 125) {
540                                 retval = EINVAL;
541                                 break;
542                         }
543                         FCPARAM(isp)->isp_loopid = param;
544                         retval = 0;
545                         break;
546                 }
547                 retval = EINVAL;
548                 break;
549         }
550         case ISP_TSK_MGMT:
551         {
552                 int needmarker;
553                 struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
554                 uint16_t loopid;
555                 mbreg_t mbs;
556
557                 if (IS_SCSI(isp)) {
558                         break;
559                 }
560
561                 memset(&mbs, 0, sizeof (mbs));
562                 needmarker = retval = 0;
563                 loopid = fct->loopid;
564                 if (IS_2KLOGIN(isp) == 0) {
565                         loopid <<= 8;
566                 }
567                 switch (fct->action) {
568                 case IPT_CLEAR_ACA:
569                         mbs.param[0] = MBOX_CLEAR_ACA;
570                         mbs.param[1] = loopid;
571                         mbs.param[2] = fct->lun;
572                         break;
573                 case IPT_TARGET_RESET:
574                         mbs.param[0] = MBOX_TARGET_RESET;
575                         mbs.param[1] = loopid;
576                         needmarker = 1;
577                         break;
578                 case IPT_LUN_RESET:
579                         mbs.param[0] = MBOX_LUN_RESET;
580                         mbs.param[1] = loopid;
581                         mbs.param[2] = fct->lun;
582                         needmarker = 1;
583                         break;
584                 case IPT_CLEAR_TASK_SET:
585                         mbs.param[0] = MBOX_CLEAR_TASK_SET;
586                         mbs.param[1] = loopid;
587                         mbs.param[2] = fct->lun;
588                         needmarker = 1;
589                         break;
590                 case IPT_ABORT_TASK_SET:
591                         mbs.param[0] = MBOX_ABORT_TASK_SET;
592                         mbs.param[1] = loopid;
593                         mbs.param[2] = fct->lun;
594                         needmarker = 1;
595                         break;
596                 default:
597                         retval = EINVAL;
598                         break;
599                 }
600                 if (retval == 0) {
601                         ISP_LOCK(isp);
602                         if (needmarker) {
603                                 isp->isp_sendmarker |= 1;
604                         }
605                         retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
606                         ISP_UNLOCK(isp);
607                         if (retval)
608                                 retval = EIO;
609                 }
610                 break;
611         }
612         default:
613                 break;
614         }
615         return (retval);
616 }
617
618 static void
619 isp_intr_enable(void *arg)
620 {
621         ispsoftc_t *isp = arg;
622         if (isp->isp_role != ISP_ROLE_NONE) {
623                 ENABLE_INTS(isp);
624 #if     0
625                 isp->isp_osinfo.intsok = 1;
626 #endif
627         }
628         /* Release our hook so that the boot can continue. */
629         config_intrhook_disestablish(&isp->isp_osinfo.ehook);
630 }
631
632 /*
633  * Put the target mode functions here, because some are inlines
634  */
635
636 #ifdef  ISP_TARGET_MODE
637
638 static __inline int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
639 static __inline int are_any_luns_enabled(ispsoftc_t *, int);
640 static __inline tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
641 static __inline void rls_lun_statep(ispsoftc_t *, tstate_t *);
642 static __inline atio_private_data_t *isp_get_atpd(ispsoftc_t *, int);
643 static cam_status
644 create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
645 static void destroy_lun_state(ispsoftc_t *, tstate_t *);
646 static int isp_en_lun(ispsoftc_t *, union ccb *);
647 static void isp_ledone(ispsoftc_t *, lun_entry_t *);
648 static cam_status isp_abort_tgt_ccb(ispsoftc_t *, union ccb *);
649 static timeout_t isp_refire_putback_atio;
650 static void isp_complete_ctio(union ccb *);
651 static void isp_target_putback_atio(union ccb *);
652 static void isp_target_start_ctio(ispsoftc_t *, union ccb *);
653 static int isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
654 static int isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
655 static int isp_handle_platform_ctio(ispsoftc_t *, void *);
656 static int isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *);
657 static int isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
658
659 static __inline int
660 is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
661 {
662         tstate_t *tptr;
663         tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
664         if (tptr == NULL) {
665                 return (0);
666         }
667         do {
668                 if (tptr->lun == (lun_id_t) lun && tptr->bus == bus) {
669                         return (1);
670                 }
671         } while ((tptr = tptr->next) != NULL);
672         return (0);
673 }
674
675 static __inline int
676 are_any_luns_enabled(ispsoftc_t *isp, int port)
677 {
678         int lo, hi;
679         if (IS_DUALBUS(isp)) {
680                 lo = (port * (LUN_HASH_SIZE >> 1));
681                 hi = lo + (LUN_HASH_SIZE >> 1);
682         } else {
683                 lo = 0;
684                 hi = LUN_HASH_SIZE;
685         }
686         for (lo = 0; lo < hi; lo++) {
687                 if (isp->isp_osinfo.lun_hash[lo]) {
688                         return (1);
689                 }
690         }
691         return (0);
692 }
693
694 static __inline tstate_t *
695 get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
696 {
697         tstate_t *tptr = NULL;
698
699         if (lun == CAM_LUN_WILDCARD) {
700                 if (isp->isp_osinfo.tmflags[bus] & TM_WILDCARD_ENABLED) {
701                         tptr = &isp->isp_osinfo.tsdflt[bus];
702                         tptr->hold++;
703                         return (tptr);
704                 }
705                 return (NULL);
706         } else {
707                 tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
708                 if (tptr == NULL) {
709                         return (NULL);
710                 }
711         }
712
713         do {
714                 if (tptr->lun == lun && tptr->bus == bus) {
715                         tptr->hold++;
716                         return (tptr);
717                 }
718         } while ((tptr = tptr->next) != NULL);
719         return (tptr);
720 }
721
722 static __inline void
723 rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
724 {
725         if (tptr->hold)
726                 tptr->hold--;
727 }
728
729 static __inline atio_private_data_t *
730 isp_get_atpd(ispsoftc_t *isp, int tag)
731 {
732         atio_private_data_t *atp;
733         for (atp = isp->isp_osinfo.atpdp;
734             atp < &isp->isp_osinfo.atpdp[ATPDPSIZE]; atp++) {
735                 if (atp->tag == tag)
736                         return (atp);
737         }
738         return (NULL);
739 }
740
741 static cam_status
742 create_lun_state(ispsoftc_t *isp, int bus,
743     struct cam_path *path, tstate_t **rslt)
744 {
745         cam_status status;
746         lun_id_t lun;
747         int hfx;
748         tstate_t *tptr, *new;
749
750         lun = xpt_path_lun_id(path);
751         if (lun < 0) {
752                 return (CAM_LUN_INVALID);
753         }
754         if (is_lun_enabled(isp, bus, lun)) {
755                 return (CAM_LUN_ALRDY_ENA);
756         }
757         new = (tstate_t *) malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
758         if (new == NULL) {
759                 return (CAM_RESRC_UNAVAIL);
760         }
761
762         status = xpt_create_path(&new->owner, NULL, xpt_path_path_id(path),
763             xpt_path_target_id(path), xpt_path_lun_id(path));
764         if (status != CAM_REQ_CMP) {
765                 free(new, M_DEVBUF);
766                 return (status);
767         }
768         new->bus = bus;
769         new->lun = lun;
770         SLIST_INIT(&new->atios);
771         SLIST_INIT(&new->inots);
772         new->hold = 1;
773
774         hfx = LUN_HASH_FUNC(isp, new->bus, new->lun);
775         tptr = isp->isp_osinfo.lun_hash[hfx];
776         if (tptr == NULL) {
777                 isp->isp_osinfo.lun_hash[hfx] = new;
778         } else {
779                 while (tptr->next)
780                         tptr = tptr->next;
781                 tptr->next = new;
782         }
783         *rslt = new;
784         return (CAM_REQ_CMP);
785 }
786
787 static __inline void
788 destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
789 {
790         int hfx;
791         tstate_t *lw, *pw;
792
793         if (tptr->hold) {
794                 return;
795         }
796         hfx = LUN_HASH_FUNC(isp, tptr->bus, tptr->lun);
797         pw = isp->isp_osinfo.lun_hash[hfx];
798         if (pw == NULL) {
799                 return;
800         } else if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
801                 isp->isp_osinfo.lun_hash[hfx] = pw->next;
802         } else {
803                 lw = pw;
804                 pw = lw->next;
805                 while (pw) {
806                         if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
807                                 lw->next = pw->next;
808                                 break;
809                         }
810                         lw = pw;
811                         pw = pw->next;
812                 }
813                 if (pw == NULL) {
814                         return;
815                 }
816         }
817         free(tptr, M_DEVBUF);
818 }
819
820 /*
821  * Enable luns.
822  */
823 static int
824 isp_en_lun(ispsoftc_t *isp, union ccb *ccb)
825 {
826         struct ccb_en_lun *cel = &ccb->cel;
827         tstate_t *tptr;
828         uint32_t seq;
829         int bus, cmd, av, wildcard, tm_on;
830         lun_id_t lun;
831         target_id_t tgt;
832
833         bus = XS_CHANNEL(ccb);
834         if (bus > 1) {
835                 xpt_print_path(ccb->ccb_h.path);
836                 printf("illegal bus %d\n", bus);
837                 ccb->ccb_h.status = CAM_PATH_INVALID;
838                 return (-1);
839         }
840         tgt = ccb->ccb_h.target_id;
841         lun = ccb->ccb_h.target_lun;
842
843         isp_prt(isp, ISP_LOGTDEBUG0,
844             "isp_en_lun: %sabling lun 0x%x on channel %d",
845             cel->enable? "en" : "dis", lun, bus);
846
847
848         if ((lun != CAM_LUN_WILDCARD) &&
849             (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns)) {
850                 ccb->ccb_h.status = CAM_LUN_INVALID;
851                 return (-1);
852         }
853
854         if (IS_SCSI(isp)) {
855                 sdparam *sdp = isp->isp_param;
856                 sdp += bus;
857                 if (tgt != CAM_TARGET_WILDCARD &&
858                     tgt != sdp->isp_initiator_id) {
859                         ccb->ccb_h.status = CAM_TID_INVALID;
860                         return (-1);
861                 }
862         } else {
863                 /*
864                  * There's really no point in doing this yet w/o multi-tid
865                  * capability. Even then, it's problematic.
866                  */
867 #if     0
868                 if (tgt != CAM_TARGET_WILDCARD &&
869                     tgt != FCPARAM(isp)->isp_iid) {
870                         ccb->ccb_h.status = CAM_TID_INVALID;
871                         return (-1);
872                 }
873 #endif
874                 /*
875                  * This is as a good a place as any to check f/w capabilities.
876                  */
877                 if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_TMODE) == 0) {
878                         isp_prt(isp, ISP_LOGERR,
879                             "firmware does not support target mode");
880                         ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
881                         return (-1);
882                 }
883                 /*
884                  * XXX: We *could* handle non-SCCLUN f/w, but we'd have to
885                  * XXX: dorks with our already fragile enable/disable code.
886                  */
887                 if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
888                         isp_prt(isp, ISP_LOGERR,
889                             "firmware not SCCLUN capable");
890                         ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
891                         return (-1);
892                 }
893         }
894
895         if (tgt == CAM_TARGET_WILDCARD) {
896                 if (lun == CAM_LUN_WILDCARD) {
897                         wildcard = 1;
898                 } else {
899                         ccb->ccb_h.status = CAM_LUN_INVALID;
900                         return (-1);
901                 }
902         } else {
903                 wildcard = 0;
904         }
905
906         tm_on = (isp->isp_osinfo.tmflags[bus] & TM_TMODE_ENABLED) != 0;
907
908         /*
909          * Next check to see whether this is a target/lun wildcard action.
910          *
911          * If so, we know that we can accept commands for luns that haven't
912          * been enabled yet and send them upstream. Otherwise, we have to
913          * handle them locally (if we see them at all).
914          */
915
916         if (wildcard) {
917                 tptr = &isp->isp_osinfo.tsdflt[bus];
918                 if (cel->enable) {
919                         if (tm_on) {
920                                 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
921                                 return (-1);
922                         }
923                         ccb->ccb_h.status =
924                             xpt_create_path(&tptr->owner, NULL,
925                             xpt_path_path_id(ccb->ccb_h.path),
926                             xpt_path_target_id(ccb->ccb_h.path),
927                             xpt_path_lun_id(ccb->ccb_h.path));
928                         if (ccb->ccb_h.status != CAM_REQ_CMP) {
929                                 return (-1);
930                         }
931                         SLIST_INIT(&tptr->atios);
932                         SLIST_INIT(&tptr->inots);
933                         isp->isp_osinfo.tmflags[bus] |= TM_WILDCARD_ENABLED;
934                 } else {
935                         if (tm_on == 0) {
936                                 ccb->ccb_h.status = CAM_REQ_CMP;
937                                 return (-1);
938                         }
939                         if (tptr->hold) {
940                                 ccb->ccb_h.status = CAM_SCSI_BUSY;
941                                 return (-1);
942                         }
943                         xpt_free_path(tptr->owner);
944                         isp->isp_osinfo.tmflags[bus] &= ~TM_WILDCARD_ENABLED;
945                 }
946         }
947
948         /*
949          * Now check to see whether this bus needs to be
950          * enabled/disabled with respect to target mode.
951          */
952         av = bus << 31;
953         if (cel->enable && tm_on == 0) {
954                 av |= ENABLE_TARGET_FLAG;
955                 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
956                 if (av) {
957                         ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
958                         if (wildcard) {
959                                 isp->isp_osinfo.tmflags[bus] &=
960                                     ~TM_WILDCARD_ENABLED;
961                                 xpt_free_path(tptr->owner);
962                         }
963                         return (-1);
964                 }
965                 isp->isp_osinfo.tmflags[bus] |= TM_TMODE_ENABLED;
966                 isp_prt(isp, ISP_LOGINFO,
967                     "Target Mode enabled on channel %d", bus);
968         } else if (cel->enable == 0 && tm_on && wildcard) {
969                 if (are_any_luns_enabled(isp, bus)) {
970                         ccb->ccb_h.status = CAM_SCSI_BUSY;
971                         return (-1);
972                 }
973                 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
974                 if (av) {
975                         ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
976                         return (-1);
977                 }
978                 isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
979                 isp_prt(isp, ISP_LOGINFO,
980                     "Target Mode disabled on channel %d", bus);
981         }
982
983         if (wildcard) {
984                 ccb->ccb_h.status = CAM_REQ_CMP;
985                 return (-1);
986         }
987
988         /*
989          * Find an empty slot
990          */
991         for (seq = 0; seq < NLEACT; seq++) {
992                 if (isp->isp_osinfo.leact[seq] == 0) {
993                         break;
994                 }
995         }
996         if (seq >= NLEACT) {
997                 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
998                 return (-1);
999                 
1000         }
1001         isp->isp_osinfo.leact[seq] = ccb;
1002
1003         if (cel->enable) {
1004                 ccb->ccb_h.status =
1005                     create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
1006                 if (ccb->ccb_h.status != CAM_REQ_CMP) {
1007                         isp->isp_osinfo.leact[seq] = 0;
1008                         return (-1);
1009                 }
1010         } else {
1011                 tptr = get_lun_statep(isp, bus, lun);
1012                 if (tptr == NULL) {
1013                         ccb->ccb_h.status = CAM_LUN_INVALID;
1014                         return (-1);
1015                 }
1016         }
1017
1018         if (cel->enable) {
1019                 int c, n, ulun = lun;
1020
1021                 cmd = RQSTYPE_ENABLE_LUN;
1022                 c = DFLT_CMND_CNT;
1023                 n = DFLT_INOT_CNT;
1024                 if (IS_FC(isp) && lun != 0) {
1025                         cmd = RQSTYPE_MODIFY_LUN;
1026                         n = 0;
1027                         /*
1028                          * For SCC firmware, we only deal with setting
1029                          * (enabling or modifying) lun 0.
1030                          */
1031                         ulun = 0;
1032                 }
1033                 if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
1034                         rls_lun_statep(isp, tptr);
1035                         ccb->ccb_h.status = CAM_REQ_INPROG;
1036                         return (seq);
1037                 }
1038         } else {
1039                 int c, n, ulun = lun;
1040
1041                 cmd = -RQSTYPE_MODIFY_LUN;
1042                 c = DFLT_CMND_CNT;
1043                 n = DFLT_INOT_CNT;
1044                 if (IS_FC(isp) && lun != 0) {
1045                         n = 0;
1046                         /*
1047                          * For SCC firmware, we only deal with setting
1048                          * (enabling or modifying) lun 0.
1049                          */
1050                         ulun = 0;
1051                 }
1052                 if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
1053                         rls_lun_statep(isp, tptr);
1054                         ccb->ccb_h.status = CAM_REQ_INPROG;
1055                         return (seq);
1056                 }
1057         }
1058         rls_lun_statep(isp, tptr);
1059         xpt_print_path(ccb->ccb_h.path);
1060         printf("isp_lun_cmd failed\n");
1061         isp->isp_osinfo.leact[seq] = 0;
1062         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1063         return (-1);
1064 }
1065
1066 static void
1067 isp_ledone(ispsoftc_t *isp, lun_entry_t *lep)
1068 {
1069         const char lfmt[] = "lun %d now %sabled for target mode on channel %d";
1070         union ccb *ccb;
1071         uint32_t seq;
1072         tstate_t *tptr;
1073         int av;
1074         struct ccb_en_lun *cel;
1075
1076         seq = lep->le_reserved - 1;
1077         if (seq >= NLEACT) {
1078                 isp_prt(isp, ISP_LOGERR,
1079                     "seq out of range (%u) in isp_ledone", seq);
1080                 return;
1081         }
1082         ccb = isp->isp_osinfo.leact[seq];
1083         if (ccb == 0) {
1084                 isp_prt(isp, ISP_LOGERR,
1085                     "no ccb for seq %u in isp_ledone", seq);
1086                 return;
1087         }
1088         cel = &ccb->cel;
1089         tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
1090         if (tptr == NULL) {
1091                 xpt_print_path(ccb->ccb_h.path);
1092                 printf("null tptr in isp_ledone\n");
1093                 isp->isp_osinfo.leact[seq] = 0;
1094                 return;
1095         }
1096
1097         if (lep->le_status != LUN_OK) {
1098                 xpt_print_path(ccb->ccb_h.path);
1099                 printf("ENABLE/MODIFY LUN returned 0x%x\n", lep->le_status);
1100 err:
1101                 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1102                 xpt_print_path(ccb->ccb_h.path);
1103                 rls_lun_statep(isp, tptr);
1104                 isp->isp_osinfo.leact[seq] = 0;
1105                 ISPLOCK_2_CAMLOCK(isp);
1106                 xpt_done(ccb);
1107                 CAMLOCK_2_ISPLOCK(isp);
1108                 return;
1109         } else {
1110                 isp_prt(isp, ISP_LOGTDEBUG0,
1111                     "isp_ledone: ENABLE/MODIFY done okay");
1112         }
1113
1114
1115         if (cel->enable) {
1116                 ccb->ccb_h.status = CAM_REQ_CMP;
1117                 isp_prt(isp, ISP_LOGINFO, lfmt,
1118                     XS_LUN(ccb), "en", XS_CHANNEL(ccb));
1119                 rls_lun_statep(isp, tptr);
1120                 isp->isp_osinfo.leact[seq] = 0;
1121                 ISPLOCK_2_CAMLOCK(isp);
1122                 xpt_done(ccb);
1123                 CAMLOCK_2_ISPLOCK(isp);
1124                 return;
1125         }
1126
1127         if (lep->le_header.rqs_entry_type == RQSTYPE_MODIFY_LUN) {
1128                 if (isp_lun_cmd(isp, -RQSTYPE_ENABLE_LUN, XS_CHANNEL(ccb),
1129                     XS_TGT(ccb), XS_LUN(ccb), 0, 0, seq+1)) {
1130                         xpt_print_path(ccb->ccb_h.path);
1131                         printf("isp_ledone: isp_lun_cmd failed\n");
1132                         goto err;
1133                 }
1134                 rls_lun_statep(isp, tptr);
1135                 return;
1136         }
1137
1138         isp_prt(isp, ISP_LOGINFO, lfmt, XS_LUN(ccb), "dis", XS_CHANNEL(ccb));
1139         rls_lun_statep(isp, tptr);
1140         destroy_lun_state(isp, tptr);
1141         ccb->ccb_h.status = CAM_REQ_CMP;
1142         isp->isp_osinfo.leact[seq] = 0;
1143         ISPLOCK_2_CAMLOCK(isp);
1144         xpt_done(ccb);
1145         CAMLOCK_2_ISPLOCK(isp);
1146         if (are_any_luns_enabled(isp, XS_CHANNEL(ccb)) == 0) {
1147                 int bus = XS_CHANNEL(ccb);
1148                 av = bus << 31;
1149                 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
1150                 if (av) {
1151                         isp_prt(isp, ISP_LOGWARN,
1152                             "disable target mode on channel %d failed", bus);
1153                 } else {
1154                         isp_prt(isp, ISP_LOGINFO,
1155                             "Target Mode disabled on channel %d", bus);
1156                 }
1157                 isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
1158         }
1159 }
1160
1161
1162 static cam_status
1163 isp_abort_tgt_ccb(ispsoftc_t *isp, union ccb *ccb)
1164 {
1165         tstate_t *tptr;
1166         struct ccb_hdr_slist *lp;
1167         struct ccb_hdr *curelm;
1168         int found, *ctr;
1169         union ccb *accb = ccb->cab.abort_ccb;
1170
1171         isp_prt(isp, ISP_LOGTDEBUG0, "aborting ccb %p", accb);
1172         if (accb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
1173                 int badpath = 0;
1174                 if (IS_FC(isp) && (accb->ccb_h.target_id != 
1175                     ((fcparam *) isp->isp_param)->isp_loopid)) {
1176                         badpath = 1;
1177                 } else if (IS_SCSI(isp) && (accb->ccb_h.target_id != 
1178                     ((sdparam *) isp->isp_param)->isp_initiator_id)) {
1179                         badpath = 1;
1180                 }
1181                 if (badpath) {
1182                         /*
1183                          * Being restrictive about target ids is really about
1184                          * making sure we're aborting for the right multi-tid
1185                          * path. This doesn't really make much sense at present.
1186                          */
1187 #if     0
1188                         return (CAM_PATH_INVALID);
1189 #endif
1190                 }
1191         }
1192         tptr = get_lun_statep(isp, XS_CHANNEL(ccb), accb->ccb_h.target_lun);
1193         if (tptr == NULL) {
1194                 isp_prt(isp, ISP_LOGTDEBUG0,
1195                     "isp_abort_tgt_ccb: can't get statep");
1196                 return (CAM_PATH_INVALID);
1197         }
1198         if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
1199                 lp = &tptr->atios;
1200                 ctr = &tptr->atio_count;
1201         } else if (accb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
1202                 lp = &tptr->inots;
1203                 ctr = &tptr->inot_count;
1204         } else {
1205                 rls_lun_statep(isp, tptr);
1206                 isp_prt(isp, ISP_LOGTDEBUG0,
1207                     "isp_abort_tgt_ccb: bad func %d\n", accb->ccb_h.func_code);
1208                 return (CAM_UA_ABORT);
1209         }
1210         curelm = SLIST_FIRST(lp);
1211         found = 0;
1212         if (curelm == &accb->ccb_h) {
1213                 found = 1;
1214                 SLIST_REMOVE_HEAD(lp, sim_links.sle);
1215         } else {
1216                 while(curelm != NULL) {
1217                         struct ccb_hdr *nextelm;
1218
1219                         nextelm = SLIST_NEXT(curelm, sim_links.sle);
1220                         if (nextelm == &accb->ccb_h) {
1221                                 found = 1;
1222                                 SLIST_NEXT(curelm, sim_links.sle) =
1223                                     SLIST_NEXT(nextelm, sim_links.sle);
1224                                 break;
1225                         }
1226                         curelm = nextelm;
1227                 }
1228         }
1229         rls_lun_statep(isp, tptr);
1230         if (found) {
1231                 (*ctr)--;
1232                 accb->ccb_h.status = CAM_REQ_ABORTED;
1233                 xpt_done(accb);
1234                 return (CAM_REQ_CMP);
1235         }
1236         isp_prt(isp, ISP_LOGTDEBUG0,
1237             "isp_abort_tgt_ccb: CCB %p not found\n", ccb);
1238         return (CAM_PATH_INVALID);
1239 }
1240
1241 static void
1242 isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
1243 {
1244         void *qe;
1245         struct ccb_scsiio *cso = &ccb->csio;
1246         uint16_t *hp, save_handle;
1247         uint16_t nxti, optr;
1248         uint8_t local[QENTRY_LEN];
1249
1250
1251         if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
1252                 xpt_print_path(ccb->ccb_h.path);
1253                 printf("Request Queue Overflow in isp_target_start_ctio\n");
1254                 XS_SETERR(ccb, CAM_REQUEUE_REQ);
1255                 goto out;
1256         }
1257         memset(local, 0, QENTRY_LEN);
1258
1259         /*
1260          * We're either moving data or completing a command here.
1261          */
1262
1263         if (IS_FC(isp)) {
1264                 atio_private_data_t *atp;
1265                 ct2_entry_t *cto = (ct2_entry_t *) local;
1266
1267                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
1268                 cto->ct_header.rqs_entry_count = 1;
1269                 if (IS_2KLOGIN(isp)) {
1270                         ((ct2e_entry_t *)cto)->ct_iid = cso->init_id;
1271                 } else {
1272                         cto->ct_iid = cso->init_id;
1273                         if (!(FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)) {
1274                                 cto->ct_lun = ccb->ccb_h.target_lun;
1275                         }
1276                 }
1277
1278                 atp = isp_get_atpd(isp, cso->tag_id);
1279                 if (atp == NULL) {
1280                         isp_prt(isp, ISP_LOGERR,
1281                             "cannot find private data adjunct for tag %x",
1282                             cso->tag_id);
1283                         XS_SETERR(ccb, CAM_REQ_CMP_ERR);
1284                         goto out;
1285                 }
1286
1287                 cto->ct_rxid = cso->tag_id;
1288                 if (cso->dxfer_len == 0) {
1289                         cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA;
1290                         if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1291                                 cto->ct_flags |= CT2_SENDSTATUS;
1292                                 cto->rsp.m1.ct_scsi_status = cso->scsi_status;
1293                                 cto->ct_resid =
1294                                     atp->orig_datalen - atp->bytes_xfered;
1295                                 if (cto->ct_resid < 0) {
1296                                         cto->rsp.m1.ct_scsi_status |=
1297                                             CT2_DATA_OVER;
1298                                 } else if (cto->ct_resid > 0) {
1299                                         cto->rsp.m1.ct_scsi_status |=
1300                                             CT2_DATA_UNDER;
1301                                 }
1302                         }
1303                         if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) {
1304                                 int m = min(cso->sense_len, MAXRESPLEN);
1305                                 memcpy(cto->rsp.m1.ct_resp,
1306                                     &cso->sense_data, m);
1307                                 cto->rsp.m1.ct_senselen = m;
1308                                 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
1309                         }
1310                 } else {
1311                         cto->ct_flags |= CT2_FLAG_MODE0;
1312                         if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1313                                 cto->ct_flags |= CT2_DATA_IN;
1314                         } else {
1315                                 cto->ct_flags |= CT2_DATA_OUT;
1316                         }
1317                         cto->ct_reloff = atp->bytes_xfered;
1318                         if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
1319                                 cto->ct_flags |= CT2_SENDSTATUS;
1320                                 cto->rsp.m0.ct_scsi_status = cso->scsi_status;
1321                                 cto->ct_resid =
1322                                     atp->orig_datalen -
1323                                     (atp->bytes_xfered + cso->dxfer_len);
1324                                 if (cto->ct_resid < 0) {
1325                                         cto->rsp.m0.ct_scsi_status |=
1326                                             CT2_DATA_OVER;
1327                                 } else if (cto->ct_resid > 0) {
1328                                         cto->rsp.m0.ct_scsi_status |=
1329                                             CT2_DATA_UNDER;
1330                                 }
1331                         } else {
1332                                 atp->last_xframt = cso->dxfer_len;
1333                         }
1334                         /*
1335                          * If we're sending data and status back together,
1336                          * we can't also send back sense data as well.
1337                          */
1338                         ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1339                 }
1340
1341                 if (cto->ct_flags & CT2_SENDSTATUS) {
1342                         isp_prt(isp, ISP_LOGTDEBUG0,
1343                             "CTIO2[%x] STATUS %x origd %u curd %u resid %u",
1344                             cto->ct_rxid, cso->scsi_status, atp->orig_datalen,
1345                             cso->dxfer_len, cto->ct_resid);
1346                         cto->ct_flags |= CT2_CCINCR;
1347                         atp->state = ATPD_STATE_LAST_CTIO;
1348                 } else {
1349                         atp->state = ATPD_STATE_CTIO;
1350                 }
1351                 cto->ct_timeout = 10;
1352                 hp = &cto->ct_syshandle;
1353         } else {
1354                 ct_entry_t *cto = (ct_entry_t *) local;
1355
1356                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
1357                 cto->ct_header.rqs_entry_count = 1;
1358                 cto->ct_iid = cso->init_id;
1359                 cto->ct_iid |= XS_CHANNEL(ccb) << 7;
1360                 cto->ct_tgt = ccb->ccb_h.target_id;
1361                 cto->ct_lun = ccb->ccb_h.target_lun;
1362                 cto->ct_fwhandle = AT_GET_HANDLE(cso->tag_id);
1363                 if (AT_HAS_TAG(cso->tag_id)) {
1364                         cto->ct_tag_val = (uint8_t) AT_GET_TAG(cso->tag_id);
1365                         cto->ct_flags |= CT_TQAE;
1366                 }
1367                 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) {
1368                         cto->ct_flags |= CT_NODISC;
1369                 }
1370                 if (cso->dxfer_len == 0) {
1371                         cto->ct_flags |= CT_NO_DATA;
1372                 } else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1373                         cto->ct_flags |= CT_DATA_IN;
1374                 } else {
1375                         cto->ct_flags |= CT_DATA_OUT;
1376                 }
1377                 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1378                         cto->ct_flags |= CT_SENDSTATUS|CT_CCINCR;
1379                         cto->ct_scsi_status = cso->scsi_status;
1380                         cto->ct_resid = cso->resid;
1381                         isp_prt(isp, ISP_LOGTDEBUG0,
1382                             "CTIO[%x] SCSI STATUS 0x%x resid %d tag_id %x",
1383                             cto->ct_fwhandle, cso->scsi_status, cso->resid,
1384                             cso->tag_id);
1385                 }
1386                 ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1387                 cto->ct_timeout = 10;
1388                 hp = &cto->ct_syshandle;
1389         }
1390
1391         if (isp_save_xs_tgt(isp, ccb, hp)) {
1392                 xpt_print_path(ccb->ccb_h.path);
1393                 printf("No XFLIST pointers for isp_target_start_ctio\n");
1394                 XS_SETERR(ccb, CAM_REQUEUE_REQ);
1395                 goto out;
1396         }
1397
1398
1399         /*
1400          * Call the dma setup routines for this entry (and any subsequent
1401          * CTIOs) if there's data to move, and then tell the f/w it's got
1402          * new things to play with. As with isp_start's usage of DMA setup,
1403          * any swizzling is done in the machine dependent layer. Because
1404          * of this, we put the request onto the queue area first in native
1405          * format.
1406          */
1407
1408         save_handle = *hp;
1409
1410         switch (ISP_DMASETUP(isp, cso, (ispreq_t *) local, &nxti, optr)) {
1411         case CMD_QUEUED:
1412                 ISP_ADD_REQUEST(isp, nxti);
1413                 ccb->ccb_h.status |= CAM_SIM_QUEUED;
1414                 return;
1415
1416         case CMD_EAGAIN:
1417                 XS_SETERR(ccb, CAM_REQUEUE_REQ);
1418                 break;
1419
1420         default:
1421                 break;
1422         }
1423         isp_destroy_tgt_handle(isp, save_handle);
1424
1425 out:
1426         ISPLOCK_2_CAMLOCK(isp);
1427         xpt_done(ccb);
1428         CAMLOCK_2_ISPLOCK(isp);
1429 }
1430
1431 static void
1432 isp_refire_putback_atio(void *arg)
1433 {
1434         int s = splcam();
1435         isp_target_putback_atio(arg);
1436         splx(s);
1437 }
1438
1439 static void
1440 isp_target_putback_atio(union ccb *ccb)
1441 {
1442         ispsoftc_t *isp;
1443         struct ccb_scsiio *cso;
1444         uint16_t nxti, optr;
1445         void *qe;
1446
1447         isp = XS_ISP(ccb);
1448
1449         if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
1450                 (void) timeout(isp_refire_putback_atio, ccb, 10);
1451                 isp_prt(isp, ISP_LOGWARN,
1452                     "isp_target_putback_atio: Request Queue Overflow"); 
1453                 return;
1454         }
1455         memset(qe, 0, QENTRY_LEN);
1456         cso = &ccb->csio;
1457         if (IS_FC(isp)) {
1458                 at2_entry_t local, *at = &local;
1459                 MEMZERO(at, sizeof (at2_entry_t));
1460                 at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
1461                 at->at_header.rqs_entry_count = 1;
1462                 if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) != 0) {
1463                         at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
1464                 } else {
1465                         at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
1466                 }
1467                 at->at_status = CT_OK;
1468                 at->at_rxid = cso->tag_id;
1469                 at->at_iid = cso->ccb_h.target_id;
1470                 isp_put_atio2(isp, at, qe);
1471         } else {
1472                 at_entry_t local, *at = &local;
1473                 MEMZERO(at, sizeof (at_entry_t));
1474                 at->at_header.rqs_entry_type = RQSTYPE_ATIO;
1475                 at->at_header.rqs_entry_count = 1;
1476                 at->at_iid = cso->init_id;
1477                 at->at_iid |= XS_CHANNEL(ccb) << 7;
1478                 at->at_tgt = cso->ccb_h.target_id;
1479                 at->at_lun = cso->ccb_h.target_lun;
1480                 at->at_status = CT_OK;
1481                 at->at_tag_val = AT_GET_TAG(cso->tag_id);
1482                 at->at_handle = AT_GET_HANDLE(cso->tag_id);
1483                 isp_put_atio(isp, at, qe);
1484         }
1485         ISP_TDQE(isp, "isp_target_putback_atio", (int) optr, qe);
1486         ISP_ADD_REQUEST(isp, nxti);
1487         isp_complete_ctio(ccb);
1488 }
1489
1490 static void
1491 isp_complete_ctio(union ccb *ccb)
1492 {
1493         ISPLOCK_2_CAMLOCK(isp);
1494         if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
1495                 ccb->ccb_h.status |= CAM_REQ_CMP;
1496         }
1497         ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1498         xpt_done(ccb);
1499         CAMLOCK_2_ISPLOCK(isp);
1500 }
1501
1502 /*
1503  * Handle ATIO stuff that the generic code can't.
1504  * This means handling CDBs.
1505  */
1506
1507 static int
1508 isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep)
1509 {
1510         tstate_t *tptr;
1511         int status, bus, iswildcard;
1512         struct ccb_accept_tio *atiop;
1513
1514         /*
1515          * The firmware status (except for the QLTM_SVALID bit)
1516          * indicates why this ATIO was sent to us.
1517          *
1518          * If QLTM_SVALID is set, the firware has recommended Sense Data.
1519          *
1520          * If the DISCONNECTS DISABLED bit is set in the flags field,
1521          * we're still connected on the SCSI bus.
1522          */
1523         status = aep->at_status;
1524         if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
1525                 /*
1526                  * Bus Phase Sequence error. We should have sense data
1527                  * suggested by the f/w. I'm not sure quite yet what
1528                  * to do about this for CAM.
1529                  */
1530                 isp_prt(isp, ISP_LOGWARN, "PHASE ERROR");
1531                 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1532                 return (0);
1533         }
1534         if ((status & ~QLTM_SVALID) != AT_CDB) {
1535                 isp_prt(isp, ISP_LOGWARN, "bad atio (0x%x) leaked to platform",
1536                     status);
1537                 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1538                 return (0);
1539         }
1540
1541         bus = GET_BUS_VAL(aep->at_iid);
1542         tptr = get_lun_statep(isp, bus, aep->at_lun);
1543         if (tptr == NULL) {
1544                 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
1545                 if (tptr == NULL) {
1546                         /*
1547                          * Because we can't autofeed sense data back with
1548                          * a command for parallel SCSI, we can't give back
1549                          * a CHECK CONDITION. We'll give back a BUSY status
1550                          * instead. This works out okay because the only
1551                          * time we should, in fact, get this, is in the
1552                          * case that somebody configured us without the
1553                          * blackhole driver, so they get what they deserve.
1554                          */
1555                         isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1556                         return (0);
1557                 }
1558                 iswildcard = 1;
1559         } else {
1560                 iswildcard = 0;
1561         }
1562
1563         atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1564         if (atiop == NULL) {
1565                 /*
1566                  * Because we can't autofeed sense data back with
1567                  * a command for parallel SCSI, we can't give back
1568                  * a CHECK CONDITION. We'll give back a QUEUE FULL status
1569                  * instead. This works out okay because the only time we
1570                  * should, in fact, get this, is in the case that we've
1571                  * run out of ATIOS.
1572                  */
1573                 xpt_print_path(tptr->owner);
1574                 isp_prt(isp, ISP_LOGWARN,
1575                     "no ATIOS for lun %d from initiator %d on channel %d",
1576                     aep->at_lun, GET_IID_VAL(aep->at_iid), bus);
1577                 if (aep->at_flags & AT_TQAE)
1578                         isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1579                 else
1580                         isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1581                 rls_lun_statep(isp, tptr);
1582                 return (0);
1583         }
1584         SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1585         tptr->atio_count--;
1586         isp_prt(isp, ISP_LOGTDEBUG0, "Take FREE ATIO lun %d, count now %d",
1587             aep->at_lun, tptr->atio_count);
1588         if (iswildcard) {
1589                 atiop->ccb_h.target_id = aep->at_tgt;
1590                 atiop->ccb_h.target_lun = aep->at_lun;
1591         }
1592         if (aep->at_flags & AT_NODISC) {
1593                 atiop->ccb_h.flags = CAM_DIS_DISCONNECT;
1594         } else {
1595                 atiop->ccb_h.flags = 0;
1596         }
1597
1598         if (status & QLTM_SVALID) {
1599                 size_t amt = imin(QLTM_SENSELEN, sizeof (atiop->sense_data));
1600                 atiop->sense_len = amt;
1601                 MEMCPY(&atiop->sense_data, aep->at_sense, amt);
1602         } else {
1603                 atiop->sense_len = 0;
1604         }
1605
1606         atiop->init_id = GET_IID_VAL(aep->at_iid);
1607         atiop->cdb_len = aep->at_cdblen;
1608         MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
1609         atiop->ccb_h.status = CAM_CDB_RECVD;
1610         /*
1611          * Construct a tag 'id' based upon tag value (which may be 0..255)
1612          * and the handle (which we have to preserve).
1613          */
1614         AT_MAKE_TAGID(atiop->tag_id,  device_get_unit(isp->isp_dev), aep);
1615         if (aep->at_flags & AT_TQAE) {
1616                 atiop->tag_action = aep->at_tag_type;
1617                 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
1618         }
1619         xpt_done((union ccb*)atiop);
1620         isp_prt(isp, ISP_LOGTDEBUG0,
1621             "ATIO[%x] CDB=0x%x bus %d iid%d->lun%d tag 0x%x ttype 0x%x %s",
1622             aep->at_handle, aep->at_cdb[0] & 0xff, GET_BUS_VAL(aep->at_iid),
1623             GET_IID_VAL(aep->at_iid), aep->at_lun, aep->at_tag_val & 0xff,
1624             aep->at_tag_type, (aep->at_flags & AT_NODISC)?
1625             "nondisc" : "disconnecting");
1626         rls_lun_statep(isp, tptr);
1627         return (0);
1628 }
1629
1630 static int
1631 isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1632 {
1633         lun_id_t lun;
1634         tstate_t *tptr;
1635         struct ccb_accept_tio *atiop;
1636         atio_private_data_t *atp;
1637
1638         /*
1639          * The firmware status (except for the QLTM_SVALID bit)
1640          * indicates why this ATIO was sent to us.
1641          *
1642          * If QLTM_SVALID is set, the firware has recommended Sense Data.
1643          */
1644         if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
1645                 isp_prt(isp, ISP_LOGWARN,
1646                     "bogus atio (0x%x) leaked to platform", aep->at_status);
1647                 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1648                 return (0);
1649         }
1650
1651         if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) != 0) {
1652                 lun = aep->at_scclun;
1653         } else {
1654                 lun = aep->at_lun;
1655         }
1656         tptr = get_lun_statep(isp, 0, lun);
1657         if (tptr == NULL) {
1658                 isp_prt(isp, ISP_LOGTDEBUG0,
1659                     "[0x%x] no state pointer for lun %d", aep->at_rxid, lun);
1660                 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
1661                 if (tptr == NULL) {
1662                         isp_endcmd(isp, aep,
1663                             SCSI_STATUS_CHECK_COND | ECMD_SVALID |
1664                             (0x5 << 12) | (0x25 << 16), 0);
1665                         return (0);
1666                 }
1667         }
1668
1669         atp = isp_get_atpd(isp, 0);
1670         atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1671         if (atiop == NULL || atp == NULL) {
1672
1673                 /*
1674                  * Because we can't autofeed sense data back with
1675                  * a command for parallel SCSI, we can't give back
1676                  * a CHECK CONDITION. We'll give back a QUEUE FULL status
1677                  * instead. This works out okay because the only time we
1678                  * should, in fact, get this, is in the case that we've
1679                  * run out of ATIOS.
1680                  */
1681                 xpt_print_path(tptr->owner);
1682                 isp_prt(isp, ISP_LOGWARN,
1683                     "no %s for lun %d from initiator %d",
1684                     (atp == NULL && atiop == NULL)? "ATIO2s *or* ATPS" :
1685                     ((atp == NULL)? "ATPs" : "ATIO2s"), lun, aep->at_iid);
1686                 rls_lun_statep(isp, tptr);
1687                 isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1688                 return (0);
1689         }
1690         atp->state = ATPD_STATE_ATIO;
1691         SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1692         tptr->atio_count--;
1693         isp_prt(isp, ISP_LOGTDEBUG0, "Take FREE ATIO lun %d, count now %d",
1694             lun, tptr->atio_count);
1695
1696         if (tptr == &isp->isp_osinfo.tsdflt[0]) {
1697                 atiop->ccb_h.target_id =
1698                     ((fcparam *)isp->isp_param)->isp_loopid;
1699                 atiop->ccb_h.target_lun = lun;
1700         }
1701         /*
1702          * We don't get 'suggested' sense data as we do with SCSI cards.
1703          */
1704         atiop->sense_len = 0;
1705
1706         atiop->init_id = aep->at_iid;
1707         atiop->cdb_len = ATIO2_CDBLEN;
1708         MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
1709         atiop->ccb_h.status = CAM_CDB_RECVD;
1710         atiop->tag_id = aep->at_rxid;
1711         switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
1712         case ATIO2_TC_ATTR_SIMPLEQ:
1713                 atiop->tag_action = MSG_SIMPLE_Q_TAG;
1714                 break;
1715         case ATIO2_TC_ATTR_HEADOFQ:
1716                 atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1717                 break;
1718         case ATIO2_TC_ATTR_ORDERED:
1719                 atiop->tag_action = MSG_ORDERED_Q_TAG;
1720                 break;
1721         case ATIO2_TC_ATTR_ACAQ:                /* ?? */
1722         case ATIO2_TC_ATTR_UNTAGGED:
1723         default:
1724                 atiop->tag_action = 0;
1725                 break;
1726         }
1727         atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
1728
1729         atp->tag = atiop->tag_id;
1730         atp->lun = lun;
1731         atp->orig_datalen = aep->at_datalen;
1732         atp->last_xframt = 0;
1733         atp->bytes_xfered = 0;
1734         atp->state = ATPD_STATE_CAM;
1735         ISPLOCK_2_CAMLOCK(siP);
1736         xpt_done((union ccb*)atiop);
1737
1738         isp_prt(isp, ISP_LOGTDEBUG0,
1739             "ATIO2[%x] CDB=0x%x iid%d->lun%d tattr 0x%x datalen %u",
1740             aep->at_rxid, aep->at_cdb[0] & 0xff, aep->at_iid,
1741             lun, aep->at_taskflags, aep->at_datalen);
1742         rls_lun_statep(isp, tptr);
1743         return (0);
1744 }
1745
1746 static int
1747 isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
1748 {
1749         union ccb *ccb;
1750         int sentstatus, ok, notify_cam, resid = 0;
1751         uint16_t tval;
1752
1753         /*
1754          * CTIO and CTIO2 are close enough....
1755          */
1756
1757         ccb = isp_find_xs_tgt(isp, ((ct_entry_t *)arg)->ct_syshandle);
1758         KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio"));
1759         isp_destroy_tgt_handle(isp, ((ct_entry_t *)arg)->ct_syshandle);
1760
1761         if (IS_FC(isp)) {
1762                 ct2_entry_t *ct = arg;
1763                 atio_private_data_t *atp = isp_get_atpd(isp, ct->ct_rxid);
1764                 if (atp == NULL) {
1765                         isp_prt(isp, ISP_LOGERR,
1766                             "cannot find adjunct for %x after I/O",
1767                             ct->ct_rxid);
1768                         return (0);
1769                 }
1770                 sentstatus = ct->ct_flags & CT2_SENDSTATUS;
1771                 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
1772                 if (ok && sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) {
1773                         ccb->ccb_h.status |= CAM_SENT_SENSE;
1774                 }
1775                 notify_cam = ct->ct_header.rqs_seqno & 0x1;
1776                 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1777                         resid = ct->ct_resid;
1778                         atp->bytes_xfered += (atp->last_xframt - resid);
1779                         atp->last_xframt = 0;
1780                 }
1781                 if (sentstatus || !ok) {
1782                         atp->tag = 0;
1783                 }
1784                 isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN,
1785                     "CTIO2[%x] sts 0x%x flg 0x%x sns %d resid %d %s",
1786                     ct->ct_rxid, ct->ct_status, ct->ct_flags,
1787                     (ccb->ccb_h.status & CAM_SENT_SENSE) != 0,
1788                     resid, sentstatus? "FIN" : "MID");
1789                 tval = ct->ct_rxid;
1790
1791                 /* XXX: should really come after isp_complete_ctio */
1792                 atp->state = ATPD_STATE_PDON;
1793         } else {
1794                 ct_entry_t *ct = arg;
1795                 sentstatus = ct->ct_flags & CT_SENDSTATUS;
1796                 ok = (ct->ct_status  & ~QLTM_SVALID) == CT_OK;
1797                 /*
1798                  * We *ought* to be able to get back to the original ATIO
1799                  * here, but for some reason this gets lost. It's just as
1800                  * well because it's squirrelled away as part of periph
1801                  * private data.
1802                  *
1803                  * We can live without it as long as we continue to use
1804                  * the auto-replenish feature for CTIOs.
1805                  */
1806                 notify_cam = ct->ct_header.rqs_seqno & 0x1;
1807                 if (ct->ct_status & QLTM_SVALID) {
1808                         char *sp = (char *)ct;
1809                         sp += CTIO_SENSE_OFFSET;
1810                         ccb->csio.sense_len =
1811                             min(sizeof (ccb->csio.sense_data), QLTM_SENSELEN);
1812                         MEMCPY(&ccb->csio.sense_data, sp, ccb->csio.sense_len);
1813                         ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
1814                 }
1815                 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1816                         resid = ct->ct_resid;
1817                 }
1818                 isp_prt(isp, ISP_LOGTDEBUG0,
1819                     "CTIO[%x] tag %x iid %d lun %d sts %x flg %x resid %d %s",
1820                     ct->ct_fwhandle, ct->ct_tag_val, ct->ct_iid, ct->ct_lun,
1821                     ct->ct_status, ct->ct_flags, resid,
1822                     sentstatus? "FIN" : "MID");
1823                 tval = ct->ct_fwhandle;
1824         }
1825         ccb->csio.resid += resid;
1826
1827         /*
1828          * We're here either because intermediate data transfers are done
1829          * and/or the final status CTIO (which may have joined with a
1830          * Data Transfer) is done.
1831          *
1832          * In any case, for this platform, the upper layers figure out
1833          * what to do next, so all we do here is collect status and
1834          * pass information along. Any DMA handles have already been
1835          * freed.
1836          */
1837         if (notify_cam == 0) {
1838                 isp_prt(isp, ISP_LOGTDEBUG0, "  INTER CTIO[0x%x] done", tval);
1839                 return (0);
1840         }
1841
1842         isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done",
1843             (sentstatus)? "  FINAL " : "MIDTERM ", tval);
1844
1845         if (!ok) {
1846                 isp_target_putback_atio(ccb);
1847         } else {
1848                 isp_complete_ctio(ccb);
1849
1850         }
1851         return (0);
1852 }
1853
1854 static int
1855 isp_handle_platform_notify_scsi(ispsoftc_t *isp, in_entry_t *inp)
1856 {
1857         return (0);     /* XXXX */
1858 }
1859
1860 static int
1861 isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
1862 {
1863
1864         switch (inp->in_status) {
1865         case IN_PORT_LOGOUT:
1866                 isp_prt(isp, ISP_LOGWARN, "port logout of iid %d",
1867                    inp->in_iid);
1868                 break;
1869         case IN_PORT_CHANGED:
1870                 isp_prt(isp, ISP_LOGWARN, "port changed for iid %d",
1871                    inp->in_iid);
1872                 break;
1873         case IN_GLOBAL_LOGO:
1874                 isp_prt(isp, ISP_LOGINFO, "all ports logged out");
1875                 break;
1876         case IN_ABORT_TASK:
1877         {
1878                 atio_private_data_t *atp = isp_get_atpd(isp, inp->in_seqid);
1879                 struct ccb_immed_notify *inot = NULL;
1880
1881                 if (atp) {
1882                         tstate_t *tptr = get_lun_statep(isp, 0, atp->lun);
1883                         if (tptr) {
1884                                 inot = (struct ccb_immed_notify *)
1885                                     SLIST_FIRST(&tptr->inots);
1886                                 if (inot) {
1887                                         tptr->inot_count--;
1888                                         SLIST_REMOVE_HEAD(&tptr->inots,
1889                                             sim_links.sle);
1890                                         isp_prt(isp, ISP_LOGTDEBUG0,
1891                                             "Take FREE INOT count now %d",
1892                                             tptr->inot_count);
1893                                 }
1894                         }
1895                         isp_prt(isp, ISP_LOGWARN,
1896                            "abort task RX_ID %x IID %d state %d",
1897                            inp->in_seqid, inp->in_iid, atp->state);
1898                 } else {
1899                         isp_prt(isp, ISP_LOGWARN,
1900                            "abort task RX_ID %x from iid %d, state unknown",
1901                            inp->in_seqid, inp->in_iid);
1902                 }
1903                 if (inot) {
1904                         inot->initiator_id = inp->in_iid;
1905                         inot->sense_len = 0;
1906                         inot->message_args[0] = MSG_ABORT_TAG;
1907                         inot->message_args[1] = inp->in_seqid & 0xff;
1908                         inot->message_args[2] = (inp->in_seqid >> 8) & 0xff;
1909                         inot->ccb_h.status = CAM_MESSAGE_RECV;
1910                         xpt_done((union ccb *)inot);
1911                 }
1912                 break;
1913         }
1914         default:
1915                 break;
1916         }
1917         return (0);
1918 }
1919 #endif
1920
1921 static void
1922 isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
1923 {
1924         struct cam_sim *sim;
1925         ispsoftc_t *isp;
1926
1927         sim = (struct cam_sim *)cbarg;
1928         isp = (ispsoftc_t *) cam_sim_softc(sim);
1929         switch (code) {
1930         case AC_LOST_DEVICE:
1931                 if (IS_SCSI(isp)) {
1932                         uint16_t oflags, nflags;
1933                         sdparam *sdp = isp->isp_param;
1934                         int tgt;
1935
1936                         tgt = xpt_path_target_id(path);
1937                         if (tgt >= 0) {
1938                                 sdp += cam_sim_bus(sim);
1939                                 ISP_LOCK(isp);
1940                                 nflags = sdp->isp_devparam[tgt].nvrm_flags;
1941 #ifndef ISP_TARGET_MODE
1942                                 nflags &= DPARM_SAFE_DFLT;
1943                                 if (isp->isp_loaded_fw) {
1944                                         nflags |= DPARM_NARROW | DPARM_ASYNC;
1945                                 }
1946 #else
1947                                 nflags = DPARM_DEFAULT;
1948 #endif
1949                                 oflags = sdp->isp_devparam[tgt].goal_flags;
1950                                 sdp->isp_devparam[tgt].goal_flags = nflags;
1951                                 sdp->isp_devparam[tgt].dev_update = 1;
1952                                 isp->isp_update |= (1 << cam_sim_bus(sim));
1953                                 (void) isp_control(isp,
1954                                     ISPCTL_UPDATE_PARAMS, NULL);
1955                                 sdp->isp_devparam[tgt].goal_flags = oflags;
1956                                 ISP_UNLOCK(isp);
1957                         }
1958                 }
1959                 break;
1960         default:
1961                 isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code);
1962                 break;
1963         }
1964 }
1965
1966 static void
1967 isp_poll(struct cam_sim *sim)
1968 {
1969         ispsoftc_t *isp = cam_sim_softc(sim);
1970         uint16_t isr, sema, mbox;
1971
1972         ISP_LOCK(isp);
1973         if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
1974                 isp_intr(isp, isr, sema, mbox);
1975         }
1976         ISP_UNLOCK(isp);
1977 }
1978
1979
1980 static void
1981 isp_watchdog(void *arg)
1982 {
1983         XS_T *xs = arg;
1984         ispsoftc_t *isp = XS_ISP(xs);
1985         uint32_t handle;
1986         int iok;
1987
1988         /*
1989          * We've decided this command is dead. Make sure we're not trying
1990          * to kill a command that's already dead by getting it's handle and
1991          * and seeing whether it's still alive.
1992          */
1993         ISP_LOCK(isp);
1994         iok = isp->isp_osinfo.intsok;
1995         isp->isp_osinfo.intsok = 0;
1996         handle = isp_find_handle(isp, xs);
1997         if (handle) {
1998                 uint16_t isr, sema, mbox;
1999
2000                 if (XS_CMD_DONE_P(xs)) {
2001                         isp_prt(isp, ISP_LOGDEBUG1,
2002                             "watchdog found done cmd (handle 0x%x)", handle);
2003                         ISP_UNLOCK(isp);
2004                         return;
2005                 }
2006
2007                 if (XS_CMD_WDOG_P(xs)) {
2008                         isp_prt(isp, ISP_LOGDEBUG2,
2009                             "recursive watchdog (handle 0x%x)", handle);
2010                         ISP_UNLOCK(isp);
2011                         return;
2012                 }
2013
2014                 XS_CMD_S_WDOG(xs);
2015                 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
2016                         isp_intr(isp, isr, sema, mbox);
2017                 }
2018                 if (XS_CMD_DONE_P(xs)) {
2019                         isp_prt(isp, ISP_LOGDEBUG2,
2020                             "watchdog cleanup for handle 0x%x", handle);
2021                         xpt_done((union ccb *) xs);
2022                 } else if (XS_CMD_GRACE_P(xs)) {
2023                         /*
2024                          * Make sure the command is *really* dead before we
2025                          * release the handle (and DMA resources) for reuse.
2026                          */
2027                         (void) isp_control(isp, ISPCTL_ABORT_CMD, arg);
2028
2029                         /*
2030                          * After this point, the comamnd is really dead.
2031                          */
2032                         if (XS_XFRLEN(xs)) {
2033                                 ISP_DMAFREE(isp, xs, handle);
2034                         } 
2035                         isp_destroy_handle(isp, handle);
2036                         xpt_print_path(xs->ccb_h.path);
2037                         isp_prt(isp, ISP_LOGWARN,
2038                             "watchdog timeout for handle 0x%x", handle);
2039                         XS_SETERR(xs, CAM_CMD_TIMEOUT);
2040                         XS_CMD_C_WDOG(xs);
2041                         isp_done(xs);
2042                 } else {
2043                         uint16_t nxti, optr;
2044                         ispreq_t local, *mp= &local, *qe;
2045
2046                         XS_CMD_C_WDOG(xs);
2047                         xs->ccb_h.timeout_ch = timeout(isp_watchdog, xs, hz);
2048                         if (isp_getrqentry(isp, &nxti, &optr, (void **) &qe)) {
2049                                 ISP_UNLOCK(isp);
2050                                 return;
2051                         }
2052                         XS_CMD_S_GRACE(xs);
2053                         MEMZERO((void *) mp, sizeof (*mp));
2054                         mp->req_header.rqs_entry_count = 1;
2055                         mp->req_header.rqs_entry_type = RQSTYPE_MARKER;
2056                         mp->req_modifier = SYNC_ALL;
2057                         mp->req_target = XS_CHANNEL(xs) << 7;
2058                         isp_put_request(isp, mp, qe);
2059                         ISP_ADD_REQUEST(isp, nxti);
2060                 }
2061         } else {
2062                 isp_prt(isp, ISP_LOGDEBUG2, "watchdog with no command");
2063         }
2064         isp->isp_osinfo.intsok = iok;
2065         ISP_UNLOCK(isp);
2066 }
2067
2068 static void
2069 isp_kthread(void *arg)
2070 {
2071         ispsoftc_t *isp = arg;
2072
2073
2074 #if __FreeBSD_version < 500000  
2075         int s;
2076
2077         s = splcam();
2078         isp->isp_osinfo.intsok = 1;
2079 #else
2080 #ifdef  ISP_SMPLOCK
2081         mtx_lock(&isp->isp_lock);
2082 #else
2083         mtx_lock(&Giant);
2084 #endif
2085 #endif
2086         /*
2087          * The first loop is for our usage where we have yet to have
2088          * gotten good fibre channel state.
2089          */
2090         for (;;) {
2091                 int wasfrozen;
2092
2093                 isp_prt(isp, ISP_LOGDEBUG0, "kthread: checking FC state");
2094                 while (isp_fc_runstate(isp, 2 * 1000000) != 0) {
2095                         isp_prt(isp, ISP_LOGDEBUG0, "kthread: FC state ungood");
2096                         if (FCPARAM(isp)->isp_fwstate != FW_READY ||
2097                             FCPARAM(isp)->isp_loopstate < LOOP_PDB_RCVD) {
2098                                 if (FCPARAM(isp)->loop_seen_once == 0 ||
2099                                     isp->isp_osinfo.ktmature == 0) {
2100                                         break;
2101                                 }
2102                         }
2103 #ifdef  ISP_SMPLOCK
2104                         msleep(isp_kthread, &isp->isp_lock,
2105                             PRIBIO, "isp_fcthrd", hz);
2106 #else
2107                         (void) tsleep(isp_kthread, PRIBIO, "isp_fcthrd", hz);
2108 #endif
2109                 }
2110
2111                 /*
2112                  * Even if we didn't get good loop state we may be
2113                  * unfreezing the SIMQ so that we can kill off
2114                  * commands (if we've never seen loop before, for example).
2115                  */
2116                 isp->isp_osinfo.ktmature = 1;
2117                 wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
2118                 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
2119                 if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
2120                         isp_prt(isp, ISP_LOGDEBUG0, "kthread: releasing simq");
2121                         ISPLOCK_2_CAMLOCK(isp);
2122                         xpt_release_simq(isp->isp_sim, 1);
2123                         CAMLOCK_2_ISPLOCK(isp);
2124                 }
2125                 isp_prt(isp, ISP_LOGDEBUG0, "kthread: waiting until called");
2126 #if __FreeBSD_version < 500000  
2127                 tsleep(&isp->isp_osinfo.kproc, PRIBIO, "isp_fc_worker", 0);
2128 #else
2129 #ifdef  ISP_SMPLOCK
2130                 cv_wait(&isp->isp_osinfo.kthread_cv, &isp->isp_lock);
2131 #else
2132                 (void) tsleep(&isp->isp_osinfo.kthread_cv, PRIBIO, "fc_cv", 0);
2133 #endif
2134 #endif
2135         }
2136 }
2137
2138 static void
2139 isp_action(struct cam_sim *sim, union ccb *ccb)
2140 {
2141         int bus, tgt, error;
2142         ispsoftc_t *isp;
2143         struct ccb_trans_settings *cts;
2144
2145         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
2146         
2147         isp = (ispsoftc_t *)cam_sim_softc(sim);
2148         ccb->ccb_h.sim_priv.entries[0].field = 0;
2149         ccb->ccb_h.sim_priv.entries[1].ptr = isp;
2150         if (isp->isp_state != ISP_RUNSTATE &&
2151             ccb->ccb_h.func_code == XPT_SCSI_IO) {
2152                 CAMLOCK_2_ISPLOCK(isp);
2153                 isp_init(isp);
2154                 if (isp->isp_state != ISP_INITSTATE) {
2155                         ISP_UNLOCK(isp);
2156                         /*
2157                          * Lie. Say it was a selection timeout.
2158                          */
2159                         ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
2160                         xpt_freeze_devq(ccb->ccb_h.path, 1);
2161                         xpt_done(ccb);
2162                         return;
2163                 }
2164                 isp->isp_state = ISP_RUNSTATE;
2165                 ISPLOCK_2_CAMLOCK(isp);
2166         }
2167         isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
2168
2169
2170         switch (ccb->ccb_h.func_code) {
2171         case XPT_SCSI_IO:       /* Execute the requested I/O operation */
2172                 /*
2173                  * Do a couple of preliminary checks...
2174                  */
2175                 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
2176                         if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
2177                                 ccb->ccb_h.status = CAM_REQ_INVALID;
2178                                 xpt_done(ccb);
2179                                 break;
2180                         }
2181                 }
2182 #ifdef  DIAGNOSTIC
2183                 if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) {
2184                         ccb->ccb_h.status = CAM_PATH_INVALID;
2185                 } else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) {
2186                         ccb->ccb_h.status = CAM_PATH_INVALID;
2187                 }
2188                 if (ccb->ccb_h.status == CAM_PATH_INVALID) {
2189                         isp_prt(isp, ISP_LOGERR,
2190                             "invalid tgt/lun (%d.%d) in XPT_SCSI_IO",
2191                             ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2192                         xpt_done(ccb);
2193                         break;
2194                 }
2195 #endif
2196                 ((struct ccb_scsiio *) ccb)->scsi_status = SCSI_STATUS_OK;
2197                 CAMLOCK_2_ISPLOCK(isp);
2198                 error = isp_start((XS_T *) ccb);
2199                 switch (error) {
2200                 case CMD_QUEUED:
2201                         ccb->ccb_h.status |= CAM_SIM_QUEUED;
2202                         if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
2203                                 uint64_t ticks = (uint64_t) hz;
2204                                 if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT)
2205                                         ticks = 60 * 1000 * ticks;
2206                                 else
2207                                         ticks = ccb->ccb_h.timeout * hz;
2208                                 ticks = ((ticks + 999) / 1000) + hz + hz;
2209                                 if (ticks >= 0x80000000) {
2210                                         isp_prt(isp, ISP_LOGERR,
2211                                             "timeout overflow");
2212                                         ticks = 0x7fffffff;
2213                                 }
2214                                 ccb->ccb_h.timeout_ch = timeout(isp_watchdog,
2215                                     (caddr_t)ccb, (int)ticks);
2216                         } else {
2217                                 callout_handle_init(&ccb->ccb_h.timeout_ch);
2218                         }
2219                         ISPLOCK_2_CAMLOCK(isp);
2220                         break;
2221                 case CMD_RQLATER:
2222                         /*
2223                          * This can only happen for Fibre Channel
2224                          */
2225                         KASSERT((IS_FC(isp)), ("CMD_RQLATER for FC only"));
2226                         if (FCPARAM(isp)->loop_seen_once == 0 &&
2227                             isp->isp_osinfo.ktmature) {
2228                                 ISPLOCK_2_CAMLOCK(isp);
2229                                 XS_SETERR(ccb, CAM_SEL_TIMEOUT);
2230                                 xpt_done(ccb);
2231                                 break;
2232                         }
2233 #if __FreeBSD_version < 500000  
2234                         wakeup(&isp->isp_osinfo.kproc);
2235 #else
2236 #ifdef  ISP_SMPLOCK
2237                         cv_signal(&isp->isp_osinfo.kthread_cv);
2238 #else
2239                         wakeup(&isp->isp_osinfo.kthread_cv);
2240 #endif
2241 #endif
2242                         isp_freeze_loopdown(isp, "isp_action(RQLATER)");
2243                         XS_SETERR(ccb, CAM_REQUEUE_REQ);
2244                         ISPLOCK_2_CAMLOCK(isp);
2245                         xpt_done(ccb);
2246                         break;
2247                 case CMD_EAGAIN:
2248                         XS_SETERR(ccb, CAM_REQUEUE_REQ);
2249                         ISPLOCK_2_CAMLOCK(isp);
2250                         xpt_done(ccb);
2251                         break;
2252                 case CMD_COMPLETE:
2253                         isp_done((struct ccb_scsiio *) ccb);
2254                         ISPLOCK_2_CAMLOCK(isp);
2255                         break;
2256                 default:
2257                         isp_prt(isp, ISP_LOGERR,
2258                             "What's this? 0x%x at %d in file %s",
2259                             error, __LINE__, __FILE__);
2260                         XS_SETERR(ccb, CAM_REQ_CMP_ERR);
2261                         xpt_done(ccb);
2262                         ISPLOCK_2_CAMLOCK(isp);
2263                 }
2264                 break;
2265
2266 #ifdef  ISP_TARGET_MODE
2267         case XPT_EN_LUN:                /* Enable LUN as a target */
2268         {
2269                 int seq, iok, i;
2270                 CAMLOCK_2_ISPLOCK(isp);
2271                 iok = isp->isp_osinfo.intsok;
2272                 isp->isp_osinfo.intsok = 0;
2273                 seq = isp_en_lun(isp, ccb);
2274                 if (seq < 0) {
2275                         isp->isp_osinfo.intsok = iok;
2276                         ISPLOCK_2_CAMLOCK(isp);
2277                         xpt_done(ccb);
2278                         break;
2279                 }
2280                 for (i = 0; isp->isp_osinfo.leact[seq] && i < 30 * 1000; i++) {
2281                         uint16_t isr, sema, mbox;
2282                         if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
2283                                 isp_intr(isp, isr, sema, mbox);
2284                         }
2285                         DELAY(1000);
2286                 }
2287                 isp->isp_osinfo.intsok = iok;
2288                 ISPLOCK_2_CAMLOCK(isp);
2289                 break;
2290         }
2291         case XPT_NOTIFY_ACK:            /* recycle notify ack */
2292         case XPT_IMMED_NOTIFY:          /* Add Immediate Notify Resource */
2293         case XPT_ACCEPT_TARGET_IO:      /* Add Accept Target IO Resource */
2294         {
2295                 tstate_t *tptr =
2296                     get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
2297                 if (tptr == NULL) {
2298                         ccb->ccb_h.status = CAM_LUN_INVALID;
2299                         xpt_done(ccb);
2300                         break;
2301                 }
2302                 ccb->ccb_h.sim_priv.entries[0].field = 0;
2303                 ccb->ccb_h.sim_priv.entries[1].ptr = isp;
2304                 ccb->ccb_h.flags = 0;
2305
2306                 CAMLOCK_2_ISPLOCK(isp);
2307                 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
2308                         /*
2309                          * Note that the command itself may not be done-
2310                          * it may not even have had the first CTIO sent.
2311                          */
2312                         tptr->atio_count++;
2313                         isp_prt(isp, ISP_LOGTDEBUG0,
2314                             "Put FREE ATIO, lun %d, count now %d",
2315                             ccb->ccb_h.target_lun, tptr->atio_count);
2316                         SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h,
2317                             sim_links.sle);
2318                 } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
2319                         tptr->inot_count++;
2320                         isp_prt(isp, ISP_LOGTDEBUG0,
2321                             "Put FREE INOT, lun %d, count now %d",
2322                             ccb->ccb_h.target_lun, tptr->inot_count);
2323                         SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h,
2324                             sim_links.sle);
2325                 } else {
2326                         isp_prt(isp, ISP_LOGWARN, "Got Notify ACK");;
2327                 }
2328                 rls_lun_statep(isp, tptr);
2329                 ccb->ccb_h.status = CAM_REQ_INPROG;
2330                 ISPLOCK_2_CAMLOCK(isp);
2331                 break;
2332         }
2333         case XPT_CONT_TARGET_IO:
2334         {
2335                 CAMLOCK_2_ISPLOCK(isp);
2336                 isp_target_start_ctio(isp, ccb);
2337                 ISPLOCK_2_CAMLOCK(isp);
2338                 break;
2339         }
2340 #endif
2341         case XPT_RESET_DEV:             /* BDR the specified SCSI device */
2342
2343                 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
2344                 tgt = ccb->ccb_h.target_id;
2345                 tgt |= (bus << 16);
2346
2347                 CAMLOCK_2_ISPLOCK(isp);
2348                 error = isp_control(isp, ISPCTL_RESET_DEV, &tgt);
2349                 ISPLOCK_2_CAMLOCK(isp);
2350                 if (error) {
2351                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2352                 } else {
2353                         ccb->ccb_h.status = CAM_REQ_CMP;
2354                 }
2355                 xpt_done(ccb);
2356                 break;
2357         case XPT_ABORT:                 /* Abort the specified CCB */
2358         {
2359                 union ccb *accb = ccb->cab.abort_ccb;
2360                 CAMLOCK_2_ISPLOCK(isp);
2361                 switch (accb->ccb_h.func_code) {
2362 #ifdef  ISP_TARGET_MODE
2363                 case XPT_ACCEPT_TARGET_IO:
2364                 case XPT_IMMED_NOTIFY:
2365                         ccb->ccb_h.status = isp_abort_tgt_ccb(isp, ccb);
2366                         break;
2367                 case XPT_CONT_TARGET_IO:
2368                         isp_prt(isp, ISP_LOGERR, "cannot abort CTIOs yet");
2369                         ccb->ccb_h.status = CAM_UA_ABORT;
2370                         break;
2371 #endif
2372                 case XPT_SCSI_IO:
2373                         error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
2374                         if (error) {
2375                                 ccb->ccb_h.status = CAM_UA_ABORT;
2376                         } else {
2377                                 ccb->ccb_h.status = CAM_REQ_CMP;
2378                         }
2379                         break;
2380                 default:
2381                         ccb->ccb_h.status = CAM_REQ_INVALID;
2382                         break;
2383                 }
2384                 ISPLOCK_2_CAMLOCK(isp);
2385                 xpt_done(ccb);
2386                 break;
2387         }
2388 #ifdef  CAM_NEW_TRAN_CODE
2389 #define IS_CURRENT_SETTINGS(c)  (c->type == CTS_TYPE_CURRENT_SETTINGS)
2390 #else
2391 #define IS_CURRENT_SETTINGS(c)  (c->flags & CCB_TRANS_CURRENT_SETTINGS)
2392 #endif
2393         case XPT_SET_TRAN_SETTINGS:     /* Nexus Settings */
2394                 cts = &ccb->cts;
2395                 if (!IS_CURRENT_SETTINGS(cts)) {
2396                         ccb->ccb_h.status = CAM_REQ_INVALID;
2397                         xpt_done(ccb);
2398                         break;
2399                 }
2400                 tgt = cts->ccb_h.target_id;
2401                 CAMLOCK_2_ISPLOCK(isp);
2402                 if (IS_SCSI(isp)) {
2403 #ifndef CAM_NEW_TRAN_CODE
2404                         sdparam *sdp = isp->isp_param;
2405                         uint16_t *dptr;
2406
2407                         bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2408
2409                         sdp += bus;
2410                         /*
2411                          * We always update (internally) from goal_flags
2412                          * so any request to change settings just gets
2413                          * vectored to that location.
2414                          */
2415                         dptr = &sdp->isp_devparam[tgt].goal_flags;
2416
2417                         /*
2418                          * Note that these operations affect the
2419                          * the goal flags (goal_flags)- not
2420                          * the current state flags. Then we mark
2421                          * things so that the next operation to
2422                          * this HBA will cause the update to occur.
2423                          */
2424                         if (cts->valid & CCB_TRANS_DISC_VALID) {
2425                                 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
2426                                         *dptr |= DPARM_DISC;
2427                                 } else {
2428                                         *dptr &= ~DPARM_DISC;
2429                                 }
2430                         }
2431                         if (cts->valid & CCB_TRANS_TQ_VALID) {
2432                                 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
2433                                         *dptr |= DPARM_TQING;
2434                                 } else {
2435                                         *dptr &= ~DPARM_TQING;
2436                                 }
2437                         }
2438                         if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) {
2439                                 switch (cts->bus_width) {
2440                                 case MSG_EXT_WDTR_BUS_16_BIT:
2441                                         *dptr |= DPARM_WIDE;
2442                                         break;
2443                                 default:
2444                                         *dptr &= ~DPARM_WIDE;
2445                                 }
2446                         }
2447                         /*
2448                          * Any SYNC RATE of nonzero and SYNC_OFFSET
2449                          * of nonzero will cause us to go to the
2450                          * selected (from NVRAM) maximum value for
2451                          * this device. At a later point, we'll
2452                          * allow finer control.
2453                          */
2454                         if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) &&
2455                             (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) &&
2456                             (cts->sync_offset > 0)) {
2457                                 *dptr |= DPARM_SYNC;
2458                         } else {
2459                                 *dptr &= ~DPARM_SYNC;
2460                         }
2461                         *dptr |= DPARM_SAFE_DFLT;
2462 #else
2463                         struct ccb_trans_settings_scsi *scsi =
2464                             &cts->proto_specific.scsi;
2465                         struct ccb_trans_settings_spi *spi =
2466                             &cts->xport_specific.spi;
2467                         sdparam *sdp = isp->isp_param;
2468                         uint16_t *dptr;
2469
2470                         bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2471                         sdp += bus;
2472                         /*
2473                          * We always update (internally) from goal_flags
2474                          * so any request to change settings just gets
2475                          * vectored to that location.
2476                          */
2477                         dptr = &sdp->isp_devparam[tgt].goal_flags;
2478
2479                         if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
2480                                 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
2481                                         *dptr |= DPARM_DISC;
2482                                 else
2483                                         *dptr &= ~DPARM_DISC;
2484                         }
2485
2486                         if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
2487                                 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
2488                                         *dptr |= DPARM_TQING;
2489                                 else
2490                                         *dptr &= ~DPARM_TQING;
2491                         }
2492
2493                         if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
2494                                 if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
2495                                         *dptr |= DPARM_WIDE;
2496                                 else
2497                                         *dptr &= ~DPARM_WIDE;
2498                         }
2499
2500                         /*
2501                          * XXX: FIX ME
2502                          */
2503                         if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) &&
2504                             (spi->valid & CTS_SPI_VALID_SYNC_RATE) &&
2505                             (spi->sync_period && spi->sync_offset)) {
2506                                 *dptr |= DPARM_SYNC;
2507                                 /*
2508                                  * XXX: CHECK FOR LEGALITY
2509                                  */
2510                                 sdp->isp_devparam[tgt].goal_period =
2511                                     spi->sync_period;
2512                                 sdp->isp_devparam[tgt].goal_offset =
2513                                     spi->sync_offset;
2514                         } else {
2515                                 *dptr &= ~DPARM_SYNC;
2516                         }
2517 #endif
2518                         isp_prt(isp, ISP_LOGDEBUG0,
2519                             "SET bus %d targ %d to flags %x off %x per %x",
2520                             bus, tgt, sdp->isp_devparam[tgt].goal_flags,
2521                             sdp->isp_devparam[tgt].goal_offset,
2522                             sdp->isp_devparam[tgt].goal_period);
2523                         sdp->isp_devparam[tgt].dev_update = 1;
2524                         isp->isp_update |= (1 << bus);
2525                 }
2526                 ISPLOCK_2_CAMLOCK(isp);
2527                 ccb->ccb_h.status = CAM_REQ_CMP;
2528                 xpt_done(ccb);
2529                 break;
2530         case XPT_GET_TRAN_SETTINGS:
2531                 cts = &ccb->cts;
2532                 tgt = cts->ccb_h.target_id;
2533                 CAMLOCK_2_ISPLOCK(isp);
2534                 if (IS_FC(isp)) {
2535 #ifndef CAM_NEW_TRAN_CODE
2536                         /*
2537                          * a lot of normal SCSI things don't make sense.
2538                          */
2539                         cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
2540                         cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2541                         /*
2542                          * How do you measure the width of a high
2543                          * speed serial bus? Well, in bytes.
2544                          *
2545                          * Offset and period make no sense, though, so we set
2546                          * (above) a 'base' transfer speed to be gigabit.
2547                          */
2548                         cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2549 #else
2550                         fcparam *fcp = isp->isp_param;
2551                         struct ccb_trans_settings_fc *fc =
2552                             &cts->xport_specific.fc;
2553
2554                         cts->protocol = PROTO_SCSI;
2555                         cts->protocol_version = SCSI_REV_2;
2556                         cts->transport = XPORT_FC;
2557                         cts->transport_version = 0;
2558
2559                         fc->valid = CTS_FC_VALID_SPEED;
2560                         if (fcp->isp_gbspeed == 2)
2561                                 fc->bitrate = 200000;
2562                         else
2563                                 fc->bitrate = 100000;
2564                         if (tgt > 0 && tgt < MAX_FC_TARG) {
2565                                 struct lportdb *lp = &fcp->portdb[tgt];
2566                                 fc->wwnn = lp->node_wwn;
2567                                 fc->wwpn = lp->port_wwn;
2568                                 fc->port = lp->portid;
2569                                 fc->valid |= CTS_FC_VALID_WWNN |
2570                                     CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT;
2571                         }
2572 #endif
2573                 } else {
2574 #ifdef  CAM_NEW_TRAN_CODE
2575                         struct ccb_trans_settings_scsi *scsi =
2576                             &cts->proto_specific.scsi;
2577                         struct ccb_trans_settings_spi *spi =
2578                             &cts->xport_specific.spi;
2579 #endif
2580                         sdparam *sdp = isp->isp_param;
2581                         int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2582                         uint16_t dval, pval, oval;
2583
2584                         sdp += bus;
2585
2586                         if (IS_CURRENT_SETTINGS(cts)) {
2587                                 sdp->isp_devparam[tgt].dev_refresh = 1;
2588                                 isp->isp_update |= (1 << bus);
2589                                 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS,
2590                                     NULL);
2591                                 dval = sdp->isp_devparam[tgt].actv_flags;
2592                                 oval = sdp->isp_devparam[tgt].actv_offset;
2593                                 pval = sdp->isp_devparam[tgt].actv_period;
2594                         } else {
2595                                 dval = sdp->isp_devparam[tgt].nvrm_flags;
2596                                 oval = sdp->isp_devparam[tgt].nvrm_offset;
2597                                 pval = sdp->isp_devparam[tgt].nvrm_period;
2598                         }
2599
2600 #ifndef CAM_NEW_TRAN_CODE
2601                         cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
2602
2603                         if (dval & DPARM_DISC) {
2604                                 cts->flags |= CCB_TRANS_DISC_ENB;
2605                         }
2606                         if (dval & DPARM_TQING) {
2607                                 cts->flags |= CCB_TRANS_TAG_ENB;
2608                         }
2609                         if (dval & DPARM_WIDE) {
2610                                 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2611                         } else {
2612                                 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2613                         }
2614                         cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
2615                             CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2616
2617                         if ((dval & DPARM_SYNC) && oval != 0) {
2618                                 cts->sync_period = pval;
2619                                 cts->sync_offset = oval;
2620                                 cts->valid |=
2621                                     CCB_TRANS_SYNC_RATE_VALID |
2622                                     CCB_TRANS_SYNC_OFFSET_VALID;
2623                         }
2624 #else
2625                         cts->protocol = PROTO_SCSI;
2626                         cts->protocol_version = SCSI_REV_2;
2627                         cts->transport = XPORT_SPI;
2628                         cts->transport_version = 2;
2629
2630                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
2631                         spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
2632                         if (dval & DPARM_DISC) {
2633                                 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
2634                         }
2635                         if (dval & DPARM_TQING) {
2636                                 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
2637                         }
2638                         if ((dval & DPARM_SYNC) && oval && pval) {
2639                                 spi->sync_offset = oval;
2640                                 spi->sync_period = pval;
2641                                 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
2642                                 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
2643                         }
2644                         spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
2645                         if (dval & DPARM_WIDE) {
2646                                 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2647                         } else {
2648                                 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2649                         }
2650                         if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
2651                                 scsi->valid = CTS_SCSI_VALID_TQ;
2652                                 spi->valid |= CTS_SPI_VALID_DISC;
2653                         } else {
2654                                 scsi->valid = 0;
2655                         }
2656 #endif
2657                         isp_prt(isp, ISP_LOGDEBUG0,
2658                             "GET %s bus %d targ %d to flags %x off %x per %x",
2659                             IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
2660                             bus, tgt, dval, oval, pval);
2661                 }
2662                 ISPLOCK_2_CAMLOCK(isp);
2663                 ccb->ccb_h.status = CAM_REQ_CMP;
2664                 xpt_done(ccb);
2665                 break;
2666
2667         case XPT_CALC_GEOMETRY:
2668 #if __FreeBSD_version < 500000  
2669         {
2670                 struct ccb_calc_geometry *ccg;
2671                 u_int32_t secs_per_cylinder;
2672                 u_int32_t size_mb;
2673
2674                 ccg = &ccb->ccg;
2675                 if (ccg->block_size == 0) {
2676                         ccb->ccb_h.status = CAM_REQ_INVALID;
2677                         xpt_done(ccb);
2678                         break;
2679                 }
2680                 size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size);
2681                 if (size_mb > 1024) {
2682                         ccg->heads = 255;
2683                         ccg->secs_per_track = 63;
2684                 } else {
2685                         ccg->heads = 64;
2686                         ccg->secs_per_track = 32;
2687                 }
2688                 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2689                 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2690                 ccb->ccb_h.status = CAM_REQ_CMP;
2691                 xpt_done(ccb);
2692                 break;
2693         }
2694 #else
2695         {
2696                 cam_calc_geometry(&ccb->ccg, /*extended*/1);
2697                 xpt_done(ccb);
2698                 break;
2699         }
2700 #endif
2701         case XPT_RESET_BUS:             /* Reset the specified bus */
2702                 bus = cam_sim_bus(sim);
2703                 CAMLOCK_2_ISPLOCK(isp);
2704                 error = isp_control(isp, ISPCTL_RESET_BUS, &bus);
2705                 ISPLOCK_2_CAMLOCK(isp);
2706                 if (error)
2707                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2708                 else {
2709                         if (cam_sim_bus(sim) && isp->isp_path2 != NULL)
2710                                 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
2711                         else if (isp->isp_path != NULL)
2712                                 xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
2713                         ccb->ccb_h.status = CAM_REQ_CMP;
2714                 }
2715                 xpt_done(ccb);
2716                 break;
2717
2718         case XPT_TERM_IO:               /* Terminate the I/O process */
2719                 ccb->ccb_h.status = CAM_REQ_INVALID;
2720                 xpt_done(ccb);
2721                 break;
2722
2723         case XPT_PATH_INQ:              /* Path routing inquiry */
2724         {
2725                 struct ccb_pathinq *cpi = &ccb->cpi;
2726
2727                 cpi->version_num = 1;
2728 #ifdef  ISP_TARGET_MODE
2729                 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
2730 #else
2731                 cpi->target_sprt = 0;
2732 #endif
2733                 cpi->hba_eng_cnt = 0;
2734                 cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
2735                 cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
2736                 cpi->bus_id = cam_sim_bus(sim);
2737                 if (IS_FC(isp)) {
2738                         cpi->hba_misc = PIM_NOBUSRESET;
2739                         /*
2740                          * Because our loop ID can shift from time to time,
2741                          * make our initiator ID out of range of our bus.
2742                          */
2743                         cpi->initiator_id = cpi->max_target + 1;
2744
2745                         /*
2746                          * Set base transfer capabilities for Fibre Channel.
2747                          * Technically not correct because we don't know
2748                          * what media we're running on top of- but we'll
2749                          * look good if we always say 100MB/s.
2750                          */
2751                         if (FCPARAM(isp)->isp_gbspeed == 2)
2752                                 cpi->base_transfer_speed = 200000;
2753                         else
2754                                 cpi->base_transfer_speed = 100000;
2755                         cpi->hba_inquiry = PI_TAG_ABLE;
2756 #ifdef  CAM_NEW_TRAN_CODE
2757                         cpi->transport = XPORT_FC;
2758                         cpi->transport_version = 0;     /* WHAT'S THIS FOR? */
2759 #endif
2760                 } else {
2761                         sdparam *sdp = isp->isp_param;
2762                         sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
2763                         cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
2764                         cpi->hba_misc = 0;
2765                         cpi->initiator_id = sdp->isp_initiator_id;
2766                         cpi->base_transfer_speed = 3300;
2767 #ifdef  CAM_NEW_TRAN_CODE
2768                         cpi->transport = XPORT_SPI;
2769                         cpi->transport_version = 2;     /* WHAT'S THIS FOR? */
2770 #endif
2771                 }
2772 #ifdef  CAM_NEW_TRAN_CODE
2773                 cpi->protocol = PROTO_SCSI;
2774                 cpi->protocol_version = SCSI_REV_2;
2775 #endif
2776                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2777                 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
2778                 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2779                 cpi->unit_number = cam_sim_unit(sim);
2780                 cpi->ccb_h.status = CAM_REQ_CMP;
2781                 xpt_done(ccb);
2782                 break;
2783         }
2784         default:
2785                 ccb->ccb_h.status = CAM_REQ_INVALID;
2786                 xpt_done(ccb);
2787                 break;
2788         }
2789 }
2790
2791 #define ISPDDB  (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
2792 void
2793 isp_done(struct ccb_scsiio *sccb)
2794 {
2795         ispsoftc_t *isp = XS_ISP(sccb);
2796
2797         if (XS_NOERR(sccb))
2798                 XS_SETERR(sccb, CAM_REQ_CMP);
2799
2800         if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
2801             (sccb->scsi_status != SCSI_STATUS_OK)) {
2802                 sccb->ccb_h.status &= ~CAM_STATUS_MASK;
2803                 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && 
2804                     (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
2805                         sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
2806                 } else {
2807                         sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
2808                 }
2809         }
2810
2811         sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2812         if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2813                 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
2814                         sccb->ccb_h.status |= CAM_DEV_QFRZN;
2815                         xpt_freeze_devq(sccb->ccb_h.path, 1);
2816                         isp_prt(isp, ISP_LOGDEBUG0,
2817                             "freeze devq %d.%d cam sts %x scsi sts %x",
2818                             sccb->ccb_h.target_id, sccb->ccb_h.target_lun,
2819                             sccb->ccb_h.status, sccb->scsi_status);
2820                 }
2821         }
2822
2823         if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) &&
2824             (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2825                 xpt_print_path(sccb->ccb_h.path);
2826                 isp_prt(isp, ISP_LOGINFO, 
2827                     "cam completion status 0x%x", sccb->ccb_h.status);
2828         }
2829
2830         XS_CMD_S_DONE(sccb);
2831         if (XS_CMD_WDOG_P(sccb) == 0) {
2832                 untimeout(isp_watchdog, (caddr_t)sccb, sccb->ccb_h.timeout_ch);
2833                 if (XS_CMD_GRACE_P(sccb)) {
2834                         isp_prt(isp, ISP_LOGDEBUG2,
2835                             "finished command on borrowed time");
2836                 }
2837                 XS_CMD_S_CLEAR(sccb);
2838                 ISPLOCK_2_CAMLOCK(isp);
2839                 xpt_done((union ccb *) sccb);
2840                 CAMLOCK_2_ISPLOCK(isp);
2841         }
2842 }
2843
2844 int
2845 isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg)
2846 {
2847         int bus, rv = 0;
2848         switch (cmd) {
2849         case ISPASYNC_NEW_TGT_PARAMS:
2850         {
2851 #ifdef  CAM_NEW_TRAN_CODE
2852                 struct ccb_trans_settings_scsi *scsi;
2853                 struct ccb_trans_settings_spi *spi;
2854 #endif
2855                 int flags, tgt;
2856                 sdparam *sdp = isp->isp_param;
2857                 struct ccb_trans_settings cts;
2858                 struct cam_path *tmppath;
2859
2860                 memset(&cts, 0, sizeof (struct ccb_trans_settings));
2861
2862                 tgt = *((int *)arg);
2863                 bus = (tgt >> 16) & 0xffff;
2864                 tgt &= 0xffff;
2865                 sdp += bus;
2866                 ISPLOCK_2_CAMLOCK(isp);
2867                 if (xpt_create_path(&tmppath, NULL,
2868                     cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim),
2869                     tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2870                         CAMLOCK_2_ISPLOCK(isp);
2871                         isp_prt(isp, ISP_LOGWARN,
2872                             "isp_async cannot make temp path for %d.%d",
2873                             tgt, bus);
2874                         rv = -1;
2875                         break;
2876                 }
2877                 CAMLOCK_2_ISPLOCK(isp);
2878                 flags = sdp->isp_devparam[tgt].actv_flags;
2879 #ifdef  CAM_NEW_TRAN_CODE
2880                 cts.type = CTS_TYPE_CURRENT_SETTINGS;
2881                 cts.protocol = PROTO_SCSI;
2882                 cts.transport = XPORT_SPI;
2883
2884                 scsi = &cts.proto_specific.scsi;
2885                 spi = &cts.xport_specific.spi;
2886
2887                 if (flags & DPARM_TQING) {
2888                         scsi->valid |= CTS_SCSI_VALID_TQ;
2889                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
2890                         spi->flags |= CTS_SPI_FLAGS_TAG_ENB;
2891                 }
2892
2893                 if (flags & DPARM_DISC) {
2894                         spi->valid |= CTS_SPI_VALID_DISC;
2895                         spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
2896                 }
2897                 spi->flags |= CTS_SPI_VALID_BUS_WIDTH;
2898                 if (flags & DPARM_WIDE) {
2899                         spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2900                 } else {
2901                         spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2902                 }
2903                 if (flags & DPARM_SYNC) {
2904                         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
2905                         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
2906                         spi->sync_period = sdp->isp_devparam[tgt].actv_period;
2907                         spi->sync_offset = sdp->isp_devparam[tgt].actv_offset;
2908                 }
2909 #else
2910                 cts.flags = CCB_TRANS_CURRENT_SETTINGS;
2911                 cts.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2912                 if (flags & DPARM_DISC) {
2913                         cts.flags |= CCB_TRANS_DISC_ENB;
2914                 }
2915                 if (flags & DPARM_TQING) {
2916                         cts.flags |= CCB_TRANS_TAG_ENB;
2917                 }
2918                 cts.valid |= CCB_TRANS_BUS_WIDTH_VALID;
2919                 cts.bus_width = (flags & DPARM_WIDE)?
2920                     MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT;
2921                 cts.sync_period = sdp->isp_devparam[tgt].actv_period;
2922                 cts.sync_offset = sdp->isp_devparam[tgt].actv_offset;
2923                 if (flags & DPARM_SYNC) {
2924                         cts.valid |=
2925                             CCB_TRANS_SYNC_RATE_VALID |
2926                             CCB_TRANS_SYNC_OFFSET_VALID;
2927                 }
2928 #endif
2929                 isp_prt(isp, ISP_LOGDEBUG2,
2930                     "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x",
2931                     bus, tgt, sdp->isp_devparam[tgt].actv_period,
2932                     sdp->isp_devparam[tgt].actv_offset, flags);
2933                 xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
2934                 ISPLOCK_2_CAMLOCK(isp);
2935                 xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
2936                 xpt_free_path(tmppath);
2937                 CAMLOCK_2_ISPLOCK(isp);
2938                 break;
2939         }
2940         case ISPASYNC_BUS_RESET:
2941                 bus = *((int *)arg);
2942                 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected",
2943                     bus);
2944                 if (bus > 0 && isp->isp_path2) {
2945                         ISPLOCK_2_CAMLOCK(isp);
2946                         xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
2947                         CAMLOCK_2_ISPLOCK(isp);
2948                 } else if (isp->isp_path) {
2949                         ISPLOCK_2_CAMLOCK(isp);
2950                         xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
2951                         CAMLOCK_2_ISPLOCK(isp);
2952                 }
2953                 break;
2954         case ISPASYNC_LIP:
2955                 if (isp->isp_path) {
2956                         isp_freeze_loopdown(isp, "ISPASYNC_LIP");
2957                 }
2958                 isp_prt(isp, ISP_LOGINFO, "LIP Received");
2959                 break;
2960         case ISPASYNC_LOOP_RESET:
2961                 if (isp->isp_path) {
2962                         isp_freeze_loopdown(isp, "ISPASYNC_LOOP_RESET");
2963                 }
2964                 isp_prt(isp, ISP_LOGINFO, "Loop Reset Received");
2965                 break;
2966         case ISPASYNC_LOOP_DOWN:
2967                 if (isp->isp_path) {
2968                         isp_freeze_loopdown(isp, "ISPASYNC_LOOP_DOWN");
2969                 }
2970                 isp_prt(isp, ISP_LOGINFO, "Loop DOWN");
2971                 break;
2972         case ISPASYNC_LOOP_UP:
2973                 /*
2974                  * Now we just note that Loop has come up. We don't
2975                  * actually do anything because we're waiting for a
2976                  * Change Notify before activating the FC cleanup
2977                  * thread to look at the state of the loop again.
2978                  */
2979                 isp_prt(isp, ISP_LOGINFO, "Loop UP");
2980                 break;
2981         case ISPASYNC_PROMENADE:
2982         {
2983                 const char *fmt = "Target %d (Loop 0x%x) Port ID 0x%x "
2984                     "(role %s) %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x";
2985                 static const char *roles[4] = {
2986                     "(none)", "Target", "Initiator", "Target/Initiator"
2987                 };
2988                 fcparam *fcp = isp->isp_param;
2989                 int tgt = *((int *) arg);
2990 #if __FreeBSD_version >= 500000  
2991                 int is_tgt_mask = (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
2992                 struct cam_path *tmppath;
2993 #endif
2994                 struct lportdb *lp = &fcp->portdb[tgt]; 
2995
2996                 isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid,
2997                     roles[lp->roles & 0x3],
2998                     (lp->valid)? "Arrived" : "Departed",
2999                     (uint32_t) (lp->port_wwn >> 32),
3000                     (uint32_t) (lp->port_wwn & 0xffffffffLL),
3001                     (uint32_t) (lp->node_wwn >> 32),
3002                     (uint32_t) (lp->node_wwn & 0xffffffffLL));
3003
3004                 ISPLOCK_2_CAMLOCK(isp);
3005 #if __FreeBSD_version >= 500000  
3006                 if (xpt_create_path(&tmppath, NULL, cam_sim_path(isp->isp_sim),
3007                     (target_id_t)tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
3008                         CAMLOCK_2_ISPLOCK(isp);
3009                         break;
3010                 }
3011                 /*
3012                  * Policy: only announce targets.
3013                  */
3014                 if (lp->roles & is_tgt_mask) {
3015                         if (lp->valid) {
3016                                 xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
3017                         } else {
3018                                 xpt_async(AC_LOST_DEVICE, tmppath, NULL);
3019                         }
3020                 }
3021                 xpt_free_path(tmppath);
3022 #endif
3023                 CAMLOCK_2_ISPLOCK(isp);
3024                 break;
3025         }
3026         case ISPASYNC_CHANGE_NOTIFY:
3027                 if (arg == ISPASYNC_CHANGE_PDB) {
3028                         isp_prt(isp, ISP_LOGINFO,
3029                             "Port Database Changed");
3030                 } else if (arg == ISPASYNC_CHANGE_SNS) {
3031                         isp_prt(isp, ISP_LOGINFO,
3032                             "Name Server Database Changed");
3033                 }
3034 #if __FreeBSD_version < 500000  
3035                 wakeup(&isp->isp_osinfo.kproc);
3036 #else
3037 #ifdef  ISP_SMPLOCK
3038                 cv_signal(&isp->isp_osinfo.kthread_cv);
3039 #else
3040                 wakeup(&isp->isp_osinfo.kthread_cv);
3041 #endif
3042 #endif
3043                 break;
3044         case ISPASYNC_FABRIC_DEV:
3045         {
3046                 int target, base, lim;
3047                 fcparam *fcp = isp->isp_param;
3048                 struct lportdb *lp = NULL;
3049                 struct lportdb *clp = (struct lportdb *) arg;
3050                 char *pt;
3051
3052                 switch (clp->port_type) {
3053                 case 1:
3054                         pt = "   N_Port";
3055                         break;
3056                 case 2:
3057                         pt = "  NL_Port";
3058                         break;
3059                 case 3:
3060                         pt = "F/NL_Port";
3061                         break;
3062                 case 0x7f:
3063                         pt = "  Nx_Port";
3064                         break;
3065                 case 0x81:
3066                         pt = "  F_port";
3067                         break;
3068                 case 0x82:
3069                         pt = "  FL_Port";
3070                         break;
3071                 case 0x84:
3072                         pt = "   E_port";
3073                         break;
3074                 default:
3075                         pt = " ";
3076                         break;
3077                 }
3078
3079                 isp_prt(isp, ISP_LOGINFO,
3080                     "%s Fabric Device @ PortID 0x%x", pt, clp->portid);
3081
3082                 /*
3083                  * If we don't have an initiator role we bail.
3084                  *
3085                  * We just use ISPASYNC_FABRIC_DEV for announcement purposes.
3086                  */
3087
3088                 if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
3089                         break;
3090                 }
3091
3092                 /*
3093                  * Is this entry for us? If so, we bail.
3094                  */
3095
3096                 if (fcp->isp_portid == clp->portid) {
3097                         break;
3098                 }
3099
3100                 /*
3101                  * Else, the default policy is to find room for it in
3102                  * our local port database. Later, when we execute
3103                  * the call to isp_pdb_sync either this newly arrived
3104                  * or already logged in device will be (re)announced.
3105                  */
3106
3107                 if (fcp->isp_topo == TOPO_FL_PORT)
3108                         base = FC_SNS_ID+1;
3109                 else
3110                         base = 0;
3111
3112                 if (fcp->isp_topo == TOPO_N_PORT)
3113                         lim = 1;
3114                 else
3115                         lim = MAX_FC_TARG;
3116
3117                 /*
3118                  * Is it already in our list?
3119                  */
3120                 for (target = base; target < lim; target++) {
3121                         if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
3122                                 continue;
3123                         }
3124                         lp = &fcp->portdb[target];
3125                         if (lp->port_wwn == clp->port_wwn &&
3126                             lp->node_wwn == clp->node_wwn) {
3127                                 lp->fabric_dev = 1;
3128                                 break;
3129                         }
3130                 }
3131                 if (target < lim) {
3132                         break;
3133                 }
3134                 for (target = base; target < lim; target++) {
3135                         if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
3136                                 continue;
3137                         }
3138                         lp = &fcp->portdb[target];
3139                         if (lp->port_wwn == 0) {
3140                                 break;
3141                         }
3142                 }
3143                 if (target == lim) {
3144                         isp_prt(isp, ISP_LOGWARN,
3145                             "out of space for fabric devices");
3146                         break;
3147                 }
3148                 lp->port_type = clp->port_type;
3149                 lp->fc4_type = clp->fc4_type;
3150                 lp->node_wwn = clp->node_wwn;
3151                 lp->port_wwn = clp->port_wwn;
3152                 lp->portid = clp->portid;
3153                 lp->fabric_dev = 1;
3154                 break;
3155         }
3156 #ifdef  ISP_TARGET_MODE
3157         case ISPASYNC_TARGET_NOTIFY:
3158         {
3159                 tmd_notify_t *nt = arg;
3160                 isp_prt(isp, ISP_LOGALL,
3161                     "target notify code 0x%x", nt->nt_ncode);
3162                 break;
3163         }
3164         case ISPASYNC_TARGET_ACTION:
3165                 switch (((isphdr_t *)arg)->rqs_entry_type) {
3166                 default:
3167                         isp_prt(isp, ISP_LOGWARN,
3168                            "event 0x%x for unhandled target action",
3169                             ((isphdr_t *)arg)->rqs_entry_type);
3170                         break;
3171                 case RQSTYPE_NOTIFY:
3172                         if (IS_SCSI(isp)) {
3173                                 rv = isp_handle_platform_notify_scsi(isp,
3174                                     (in_entry_t *) arg);
3175                         } else {
3176                                 rv = isp_handle_platform_notify_fc(isp,
3177                                     (in_fcentry_t *) arg);
3178                         }
3179                         break;
3180                 case RQSTYPE_ATIO:
3181                         rv = isp_handle_platform_atio(isp, (at_entry_t *) arg);
3182                         break;
3183                 case RQSTYPE_ATIO2:
3184                         rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg);
3185                         break;
3186                 case RQSTYPE_CTIO3:
3187                 case RQSTYPE_CTIO2:
3188                 case RQSTYPE_CTIO:
3189                         rv = isp_handle_platform_ctio(isp, arg);
3190                         break;
3191                 case RQSTYPE_ENABLE_LUN:
3192                 case RQSTYPE_MODIFY_LUN:
3193                         isp_ledone(isp, (lun_entry_t *) arg);
3194                         break;
3195                 }
3196                 break;
3197 #endif
3198         case ISPASYNC_FW_CRASH:
3199         {
3200                 uint16_t mbox1, mbox6;
3201                 mbox1 = ISP_READ(isp, OUTMAILBOX1);
3202                 if (IS_DUALBUS(isp)) { 
3203                         mbox6 = ISP_READ(isp, OUTMAILBOX6);
3204                 } else {
3205                         mbox6 = 0;
3206                 }
3207                 isp_prt(isp, ISP_LOGERR,
3208                     "Internal Firmware Error on bus %d @ RISC Address 0x%x",
3209                     mbox6, mbox1);
3210 #ifdef  ISP_FW_CRASH_DUMP
3211                 /*
3212                  * XXX: really need a thread to do this right.
3213                  */
3214                 if (IS_FC(isp)) {
3215                         FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
3216                         FCPARAM(isp)->isp_loopstate = LOOP_NIL;
3217                         isp_freeze_loopdown(isp, "f/w crash");
3218                         isp_fw_dump(isp);
3219                 }
3220                 isp_reinit(isp);
3221                 isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
3222 #endif
3223                 break;
3224         }
3225         case ISPASYNC_UNHANDLED_RESPONSE:
3226                 break;
3227         default:
3228                 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
3229                 break;
3230         }
3231         return (rv);
3232 }
3233
3234
3235 /*
3236  * Locks are held before coming here.
3237  */
3238 void
3239 isp_uninit(ispsoftc_t *isp)
3240 {
3241         ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
3242         DISABLE_INTS(isp);
3243 }
3244
3245 void
3246 isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
3247 {
3248         va_list ap;
3249         if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
3250                 return;
3251         }
3252         printf("%s: ", device_get_nameunit(isp->isp_dev));
3253         va_start(ap, fmt);
3254         vprintf(fmt, ap);
3255         va_end(ap);
3256         printf("\n");
3257 }