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