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