2 * Copyright (c) 1997-2006 by Matthew Jacob
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice immediately at the beginning of the file, without modification,
10 * this list of conditions, and the following disclaimer.
11 * 2. The name of the author may not be used to endorse or promote products
12 * derived from this software without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 #include <dev/isp/isp_freebsd.h>
33 #include <sys/unistd.h>
34 #include <sys/kthread.h>
35 #include <machine/stdarg.h> /* for use by isp_prt below */
37 #include <sys/module.h>
38 #include <sys/ioccom.h>
39 #include <dev/isp/isp_ioctl.h>
40 #if __FreeBSD_version >= 500000
41 #include <sys/sysctl.h>
43 #include <sys/devicestat.h>
45 #include <cam/cam_periph.h>
46 #include <cam/cam_xpt_periph.h>
48 #if !defined(CAM_NEW_TRAN_CODE) && __FreeBSD_version >= 700025
49 #define CAM_NEW_TRAN_CODE 1
53 MODULE_VERSION(isp, 1);
54 MODULE_DEPEND(isp, cam, 1, 1, 1);
55 int isp_announced = 0;
56 int isp_fabric_hysteresis = 5;
57 int isp_loop_down_limit = 300; /* default loop down limit */
58 int isp_change_is_bad = 0; /* "changed" devices are bad */
59 int isp_quickboot_time = 15; /* don't wait more than N secs for loop up */
60 int isp_gone_device_time = 30; /* grace time before reporting device lost */
61 static const char *roles[4] = {
62 "(none)", "Target", "Initiator", "Target/Initiator"
64 static const char prom3[] =
65 "PortID 0x%06x Departed from Target %u because of %s";
67 static void isp_freeze_loopdown(ispsoftc_t *, char *);
68 static d_ioctl_t ispioctl;
69 static void isp_intr_enable(void *);
70 static void isp_cam_async(void *, uint32_t, struct cam_path *, void *);
71 static void isp_poll(struct cam_sim *);
72 static timeout_t isp_watchdog;
73 static timeout_t isp_ldt;
74 static void isp_kthread(void *);
75 static void isp_action(struct cam_sim *, union ccb *);
77 #if __FreeBSD_version < 700000
78 ispfwfunc *isp_get_firmware_p = NULL;
81 #if __FreeBSD_version < 500000
82 #define ISP_CDEV_MAJOR 248
83 static struct cdevsw isp_cdevsw = {
85 /* close */ nullclose,
91 /* strategy */ nostrategy,
93 /* maj */ ISP_CDEV_MAJOR,
98 #define isp_sysctl_update(x) do { ; } while (0)
100 static struct cdevsw isp_cdevsw = {
101 .d_version = D_VERSION,
102 #if __FreeBSD_version < 700037
103 .d_flags = D_NEEDGIANT,
108 static void isp_sysctl_update(ispsoftc_t *);
111 static ispsoftc_t *isplist = NULL;
114 isp_attach(ispsoftc_t *isp)
116 int primary, secondary;
117 struct ccb_setasync csa;
118 struct cam_devq *devq;
120 struct cam_path *path;
123 * Establish (in case of 12X0) which bus is the primary.
130 * Create the device queue for our SIM(s).
132 devq = cam_simq_alloc(isp->isp_maxcmds);
138 * Construct our SIM entry.
140 sim = isp_sim_alloc(isp_action, isp_poll, "isp", isp,
141 device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
147 isp->isp_osinfo.ehook.ich_func = isp_intr_enable;
148 isp->isp_osinfo.ehook.ich_arg = isp;
149 if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) {
150 cam_sim_free(sim, TRUE);
151 isp_prt(isp, ISP_LOGERR,
152 "could not establish interrupt enable hook");
156 if (xpt_bus_register(sim, primary) != CAM_SUCCESS) {
157 cam_sim_free(sim, TRUE);
161 if (xpt_create_path(&path, NULL, cam_sim_path(sim),
162 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
163 xpt_bus_deregister(cam_sim_path(sim));
164 cam_sim_free(sim, TRUE);
165 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
169 xpt_setup_ccb(&csa.ccb_h, path, 5);
170 csa.ccb_h.func_code = XPT_SASYNC_CB;
171 csa.event_enable = AC_LOST_DEVICE;
172 csa.callback = isp_cam_async;
173 csa.callback_arg = sim;
174 xpt_action((union ccb *)&csa);
176 isp->isp_path = path;
179 * If we have a second channel, construct SIM entry for that.
181 if (IS_DUALBUS(isp)) {
182 sim = isp_sim_alloc(isp_action, isp_poll, "isp", isp,
183 device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
185 xpt_bus_deregister(cam_sim_path(isp->isp_sim));
186 xpt_free_path(isp->isp_path);
188 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
191 if (xpt_bus_register(sim, secondary) != CAM_SUCCESS) {
192 xpt_bus_deregister(cam_sim_path(isp->isp_sim));
193 xpt_free_path(isp->isp_path);
194 cam_sim_free(sim, TRUE);
195 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
199 if (xpt_create_path(&path, NULL, cam_sim_path(sim),
200 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
201 xpt_bus_deregister(cam_sim_path(isp->isp_sim));
202 xpt_free_path(isp->isp_path);
203 xpt_bus_deregister(cam_sim_path(sim));
204 cam_sim_free(sim, TRUE);
205 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
209 xpt_setup_ccb(&csa.ccb_h, path, 5);
210 csa.ccb_h.func_code = XPT_SASYNC_CB;
211 csa.event_enable = AC_LOST_DEVICE;
212 csa.callback = isp_cam_async;
213 csa.callback_arg = sim;
214 xpt_action((union ccb *)&csa);
216 isp->isp_path2 = path;
220 * Create device nodes
223 (void) make_dev(&isp_cdevsw, device_get_unit(isp->isp_dev), UID_ROOT,
224 GID_OPERATOR, 0600, "%s", device_get_nameunit(isp->isp_dev));
225 isp_sysctl_update(isp);
228 if (isp->isp_role != ISP_ROLE_NONE) {
229 isp->isp_state = ISP_RUNSTATE;
230 ISP_ENABLE_INTS(isp);
232 if (isplist == NULL) {
235 ispsoftc_t *tmp = isplist;
236 while (tmp->isp_osinfo.next) {
237 tmp = tmp->isp_osinfo.next;
239 tmp->isp_osinfo.next = isp;
243 * Create a kernel thread for fibre channel instances.
246 isp_callout_init(&isp->isp_osinfo.ldt);
247 isp_callout_init(&isp->isp_osinfo.gdt);
249 #if __FreeBSD_version >= 500000
250 if (kthread_create(isp_kthread, isp, &isp->isp_osinfo.kproc,
251 RFHIGHPID, 0, "%s: fc_thrd",
252 device_get_nameunit(isp->isp_dev)))
254 if (kthread_create(isp_kthread, isp, &isp->isp_osinfo.kproc,
255 "%s: fc_thrd", device_get_nameunit(isp->isp_dev)))
259 xpt_bus_deregister(cam_sim_path(sim));
260 cam_sim_free(sim, TRUE);
261 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
262 isp_prt(isp, ISP_LOGERR, "could not create kthread");
267 * We start by being "loop down" if we have an initiator role
269 if (isp->isp_role & ISP_ROLE_INITIATOR) {
270 isp_freeze_loopdown(isp, "isp_attach");
271 isp->isp_osinfo.ldt_running = 1;
272 callout_reset(&isp->isp_osinfo.ldt,
273 isp_quickboot_time * hz, isp_ldt, isp);
274 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
275 "Starting Initial Loop Down Timer");
281 isp_freeze_loopdown(ispsoftc_t *isp, char *msg)
283 if (isp->isp_osinfo.simqfrozen == 0) {
284 isp_prt(isp, ISP_LOGDEBUG0, "%s: freeze simq (loopdown)", msg);
285 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
286 xpt_freeze_simq(isp->isp_sim, 1);
288 isp_prt(isp, ISP_LOGDEBUG0, "%s: mark frozen (loopdown)", msg);
289 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
294 #if __FreeBSD_version < 500000
296 #define _IOP struct proc
298 #define _IOP struct thread
299 #define _DEV struct cdev *
303 ispioctl(_DEV dev, u_long c, caddr_t addr, int flags, _IOP *td)
306 int nr, retval = ENOTTY;
307 #if __FreeBSD_version < 500000
315 if (minor(dev) == device_get_unit(isp->isp_dev)) {
318 isp = isp->isp_osinfo.next;
321 #if __FreeBSD_version < 500000
328 #ifdef ISP_FW_CRASH_DUMP
329 case ISP_GET_FW_CRASH_DUMP:
331 uint16_t *ptr = FCPARAM(isp)->isp_dump_data;
336 sz = QLA2200_RISC_IMAGE_DUMP_SIZE;
338 sz = QLA2300_RISC_IMAGE_DUMP_SIZE;
341 void *uaddr = *((void **) addr);
342 if (copyout(ptr, uaddr, sz)) {
352 case ISP_FORCE_CRASH_DUMP:
354 isp_freeze_loopdown(isp,
355 "ispioctl(ISP_FORCE_CRASH_DUMP)");
364 int olddblev = isp->isp_dblev;
365 isp->isp_dblev = *(int *)addr;
366 *(int *)addr = olddblev;
371 *(int *)addr = isp->isp_role;
376 if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
383 if (nr == ISP_ROLE_BOTH) {
384 isp_prt(isp, ISP_LOGERR, "dual roles not supported");
388 *(int *)addr = isp->isp_role;
397 if (isp_fc_runstate(isp, 5 * 1000000)) {
406 if (isp_control(isp, ISPCTL_SEND_LIP, 0)) {
413 case ISP_FC_GETDINFO:
415 struct isp_fc_device *ifc = (struct isp_fc_device *) addr;
421 if (ifc->loopid < 0 || ifc->loopid >= MAX_FC_TARG) {
425 lp = &FCPARAM(isp)->portdb[ifc->loopid];
426 if (lp->state == FC_PORTDB_STATE_VALID) {
427 ifc->role = lp->roles;
428 ifc->loopid = lp->handle;
429 ifc->portid = lp->portid;
430 ifc->node_wwn = lp->node_wwn;
431 ifc->port_wwn = lp->port_wwn;
440 isp_stats_t *sp = (isp_stats_t *) addr;
442 MEMZERO(sp, sizeof (*sp));
443 sp->isp_stat_version = ISP_STATS_VERSION;
444 sp->isp_type = isp->isp_type;
445 sp->isp_revision = isp->isp_revision;
446 sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt;
447 sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
448 sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
449 sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;
450 sp->isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt;
451 sp->isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt;
452 sp->isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater;
453 sp->isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater;
459 isp->isp_intbogus = 0;
460 isp->isp_intmboxc = 0;
461 isp->isp_intoasync = 0;
462 isp->isp_rsltccmplt = 0;
463 isp->isp_fphccmplt = 0;
464 isp->isp_rscchiwater = 0;
465 isp->isp_fpcchiwater = 0;
468 case ISP_FC_GETHINFO:
470 struct isp_hba_device *hba = (struct isp_hba_device *) addr;
471 MEMZERO(hba, sizeof (*hba));
473 hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev);
474 hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev);
475 hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev);
477 hba->fc_speed = FCPARAM(isp)->isp_gbspeed;
478 hba->fc_scsi_supported = 1;
479 hba->fc_topology = FCPARAM(isp)->isp_topo + 1;
480 hba->fc_loopid = FCPARAM(isp)->isp_loopid;
481 hba->nvram_node_wwn = FCPARAM(isp)->isp_wwnn_nvram;
482 hba->nvram_port_wwn = FCPARAM(isp)->isp_wwpn_nvram;
483 hba->active_node_wwn = ISP_NODEWWN(isp);
484 hba->active_port_wwn = ISP_PORTWWN(isp);
489 case ISP_GET_FC_PARAM:
491 struct isp_fc_param *f = (struct isp_fc_param *) addr;
497 if (strcmp(f->param_name, "framelength") == 0) {
498 f->parameter = FCPARAM(isp)->isp_maxfrmlen;
502 if (strcmp(f->param_name, "exec_throttle") == 0) {
503 f->parameter = FCPARAM(isp)->isp_execthrottle;
507 if (strcmp(f->param_name, "fullduplex") == 0) {
508 if (FCPARAM(isp)->isp_fwoptions & ICBOPT_FULL_DUPLEX)
513 if (strcmp(f->param_name, "loopid") == 0) {
514 f->parameter = FCPARAM(isp)->isp_loopid;
521 case ISP_SET_FC_PARAM:
523 struct isp_fc_param *f = (struct isp_fc_param *) addr;
524 uint32_t param = f->parameter;
530 if (strcmp(f->param_name, "framelength") == 0) {
531 if (param != 512 && param != 1024 && param != 1024) {
535 FCPARAM(isp)->isp_maxfrmlen = param;
539 if (strcmp(f->param_name, "exec_throttle") == 0) {
540 if (param < 16 || param > 255) {
544 FCPARAM(isp)->isp_execthrottle = param;
548 if (strcmp(f->param_name, "fullduplex") == 0) {
549 if (param != 0 && param != 1) {
554 FCPARAM(isp)->isp_fwoptions |=
557 FCPARAM(isp)->isp_fwoptions &=
563 if (strcmp(f->param_name, "loopid") == 0) {
564 if (param < 0 || param > 125) {
568 FCPARAM(isp)->isp_loopid = param;
578 struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
586 memset(&mbs, 0, sizeof (mbs));
587 needmarker = retval = 0;
588 loopid = fct->loopid;
589 if (FCPARAM(isp)->isp_2klogin == 0) {
592 switch (fct->action) {
594 mbs.param[0] = MBOX_CLEAR_ACA;
595 mbs.param[1] = loopid;
596 mbs.param[2] = fct->lun;
598 case IPT_TARGET_RESET:
599 mbs.param[0] = MBOX_TARGET_RESET;
600 mbs.param[1] = loopid;
604 mbs.param[0] = MBOX_LUN_RESET;
605 mbs.param[1] = loopid;
606 mbs.param[2] = fct->lun;
609 case IPT_CLEAR_TASK_SET:
610 mbs.param[0] = MBOX_CLEAR_TASK_SET;
611 mbs.param[1] = loopid;
612 mbs.param[2] = fct->lun;
615 case IPT_ABORT_TASK_SET:
616 mbs.param[0] = MBOX_ABORT_TASK_SET;
617 mbs.param[1] = loopid;
618 mbs.param[2] = fct->lun;
627 isp->isp_sendmarker |= 1;
629 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
638 #if __FreeBSD_version < 500000
644 #if __FreeBSD_version >= 500000
646 isp_sysctl_update(ispsoftc_t *isp)
648 struct sysctl_ctx_list *ctx =
649 device_get_sysctl_ctx(isp->isp_osinfo.dev);
650 struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev);
656 snprintf(isp->isp_osinfo.sysctl_info.fc.wwnn,
657 sizeof (isp->isp_osinfo.sysctl_info.fc.wwnn), "0x%08x%08x",
658 (uint32_t) (ISP_NODEWWN(isp) >> 32), (uint32_t) ISP_NODEWWN(isp));
660 snprintf(isp->isp_osinfo.sysctl_info.fc.wwpn,
661 sizeof (isp->isp_osinfo.sysctl_info.fc.wwpn), "0x%08x%08x",
662 (uint32_t) (ISP_PORTWWN(isp) >> 32), (uint32_t) ISP_PORTWWN(isp));
664 SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
665 "wwnn", CTLFLAG_RD, isp->isp_osinfo.sysctl_info.fc.wwnn, 0,
666 "World Wide Node Name");
668 SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
669 "wwpn", CTLFLAG_RD, isp->isp_osinfo.sysctl_info.fc.wwpn, 0,
670 "World Wide Port Name");
672 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
674 CTLFLAG_RW, &isp->isp_osinfo.loop_down_limit, 0,
675 "How long to wait for loop to come back up");
677 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
679 CTLFLAG_RW, &isp->isp_osinfo.gone_device_time, 0,
680 "How long to wait for a device to reappear");
685 isp_intr_enable(void *arg)
687 ispsoftc_t *isp = arg;
689 if (isp->isp_role != ISP_ROLE_NONE) {
690 ISP_ENABLE_INTS(isp);
693 /* Release our hook so that the boot can continue. */
694 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
698 * Put the target mode functions here, because some are inlines
701 #ifdef ISP_TARGET_MODE
703 static __inline int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
704 static __inline int are_any_luns_enabled(ispsoftc_t *, int);
705 static __inline tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
706 static __inline void rls_lun_statep(ispsoftc_t *, tstate_t *);
707 static __inline atio_private_data_t *isp_get_atpd(ispsoftc_t *, int);
709 create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
710 static void destroy_lun_state(ispsoftc_t *, tstate_t *);
711 static int isp_en_lun(ispsoftc_t *, union ccb *);
712 static void isp_ledone(ispsoftc_t *, lun_entry_t *);
713 static cam_status isp_abort_tgt_ccb(ispsoftc_t *, union ccb *);
714 static timeout_t isp_refire_putback_atio;
715 static void isp_complete_ctio(union ccb *);
716 static void isp_target_putback_atio(union ccb *);
717 static void isp_target_start_ctio(ispsoftc_t *, union ccb *);
718 static int isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
719 static int isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
720 static int isp_handle_platform_ctio(ispsoftc_t *, void *);
721 static int isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *);
722 static int isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
725 is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
728 tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
733 if (tptr->lun == (lun_id_t) lun && tptr->bus == bus) {
736 } while ((tptr = tptr->next) != NULL);
741 are_any_luns_enabled(ispsoftc_t *isp, int port)
744 if (IS_DUALBUS(isp)) {
745 lo = (port * (LUN_HASH_SIZE >> 1));
746 hi = lo + (LUN_HASH_SIZE >> 1);
751 for (lo = 0; lo < hi; lo++) {
752 if (isp->isp_osinfo.lun_hash[lo]) {
759 static __inline tstate_t *
760 get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
762 tstate_t *tptr = NULL;
764 if (lun == CAM_LUN_WILDCARD) {
765 if (isp->isp_osinfo.tmflags[bus] & TM_WILDCARD_ENABLED) {
766 tptr = &isp->isp_osinfo.tsdflt[bus];
772 tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
779 if (tptr->lun == lun && tptr->bus == bus) {
783 } while ((tptr = tptr->next) != NULL);
788 rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
794 static __inline atio_private_data_t *
795 isp_get_atpd(ispsoftc_t *isp, int tag)
797 atio_private_data_t *atp;
798 for (atp = isp->isp_osinfo.atpdp;
799 atp < &isp->isp_osinfo.atpdp[ATPDPSIZE]; atp++) {
807 create_lun_state(ispsoftc_t *isp, int bus,
808 struct cam_path *path, tstate_t **rslt)
813 tstate_t *tptr, *new;
815 lun = xpt_path_lun_id(path);
817 return (CAM_LUN_INVALID);
819 if (is_lun_enabled(isp, bus, lun)) {
820 return (CAM_LUN_ALRDY_ENA);
822 new = (tstate_t *) malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
824 return (CAM_RESRC_UNAVAIL);
827 status = xpt_create_path(&new->owner, NULL, xpt_path_path_id(path),
828 xpt_path_target_id(path), xpt_path_lun_id(path));
829 if (status != CAM_REQ_CMP) {
835 SLIST_INIT(&new->atios);
836 SLIST_INIT(&new->inots);
839 hfx = LUN_HASH_FUNC(isp, new->bus, new->lun);
840 tptr = isp->isp_osinfo.lun_hash[hfx];
842 isp->isp_osinfo.lun_hash[hfx] = new;
849 return (CAM_REQ_CMP);
853 destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
861 hfx = LUN_HASH_FUNC(isp, tptr->bus, tptr->lun);
862 pw = isp->isp_osinfo.lun_hash[hfx];
865 } else if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
866 isp->isp_osinfo.lun_hash[hfx] = pw->next;
871 if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
882 free(tptr, M_DEVBUF);
889 isp_en_lun(ispsoftc_t *isp, union ccb *ccb)
891 struct ccb_en_lun *cel = &ccb->cel;
894 int bus, cmd, av, wildcard, tm_on;
898 bus = XS_CHANNEL(ccb);
900 xpt_print(ccb->ccb_h.path, "illegal bus %d\n", bus);
901 ccb->ccb_h.status = CAM_PATH_INVALID;
904 tgt = ccb->ccb_h.target_id;
905 lun = ccb->ccb_h.target_lun;
907 if (isp->isp_dblev & ISP_LOGTDEBUG0) {
908 xpt_print(ccb->ccb_h.path, "%sabling lun 0x%x on channel %d\n",
909 cel->enable? "en" : "dis", lun, bus);
912 if ((lun != CAM_LUN_WILDCARD) &&
913 (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns)) {
914 ccb->ccb_h.status = CAM_LUN_INVALID;
919 sdparam *sdp = isp->isp_param;
921 if (tgt != CAM_TARGET_WILDCARD &&
922 tgt != sdp->isp_initiator_id) {
923 ccb->ccb_h.status = CAM_TID_INVALID;
928 * There's really no point in doing this yet w/o multi-tid
929 * capability. Even then, it's problematic.
932 if (tgt != CAM_TARGET_WILDCARD &&
933 tgt != FCPARAM(isp)->isp_iid) {
934 ccb->ccb_h.status = CAM_TID_INVALID;
939 * This is as a good a place as any to check f/w capabilities.
941 if (FCPARAM(isp)->isp_tmode == 0) {
942 xpt_print(ccb->ccb_h.path,
943 "firmware does not support target mode\n");
944 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
948 * XXX: We *could* handle non-SCCLUN f/w, but we'd have to
949 * XXX: dork with our already fragile enable/disable code.
951 if (FCPARAM(isp)->isp_sccfw == 0) {
952 xpt_print(ccb->ccb_h.path,
953 "firmware not SCCLUN capable\n");
954 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
959 if (tgt == CAM_TARGET_WILDCARD) {
960 if (lun == CAM_LUN_WILDCARD) {
963 ccb->ccb_h.status = CAM_LUN_INVALID;
970 tm_on = (isp->isp_osinfo.tmflags[bus] & TM_TMODE_ENABLED) != 0;
973 * Next check to see whether this is a target/lun wildcard action.
975 * If so, we know that we can accept commands for luns that haven't
976 * been enabled yet and send them upstream. Otherwise, we have to
977 * handle them locally (if we see them at all).
981 tptr = &isp->isp_osinfo.tsdflt[bus];
984 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
988 xpt_create_path(&tptr->owner, NULL,
989 xpt_path_path_id(ccb->ccb_h.path),
990 xpt_path_target_id(ccb->ccb_h.path),
991 xpt_path_lun_id(ccb->ccb_h.path));
992 if (ccb->ccb_h.status != CAM_REQ_CMP) {
995 SLIST_INIT(&tptr->atios);
996 SLIST_INIT(&tptr->inots);
997 isp->isp_osinfo.tmflags[bus] |= TM_WILDCARD_ENABLED;
1000 ccb->ccb_h.status = CAM_REQ_CMP;
1004 ccb->ccb_h.status = CAM_SCSI_BUSY;
1007 xpt_free_path(tptr->owner);
1008 isp->isp_osinfo.tmflags[bus] &= ~TM_WILDCARD_ENABLED;
1013 * Now check to see whether this bus needs to be
1014 * enabled/disabled with respect to target mode.
1017 if (cel->enable && tm_on == 0) {
1018 av |= ENABLE_TARGET_FLAG;
1019 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
1021 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1023 isp->isp_osinfo.tmflags[bus] &=
1024 ~TM_WILDCARD_ENABLED;
1025 xpt_free_path(tptr->owner);
1029 isp->isp_osinfo.tmflags[bus] |= TM_TMODE_ENABLED;
1030 xpt_print(ccb->ccb_h.path, "Target Mode Enabled\n");
1031 } else if (cel->enable == 0 && tm_on && wildcard) {
1032 if (are_any_luns_enabled(isp, bus)) {
1033 ccb->ccb_h.status = CAM_SCSI_BUSY;
1036 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
1038 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1041 isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
1042 xpt_print(ccb->ccb_h.path, "Target Mode Disabled\n");
1046 ccb->ccb_h.status = CAM_REQ_CMP;
1051 * Find an empty slot
1053 for (seq = 0; seq < NLEACT; seq++) {
1054 if (isp->isp_osinfo.leact[seq] == 0) {
1058 if (seq >= NLEACT) {
1059 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1063 isp->isp_osinfo.leact[seq] = ccb;
1067 create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
1068 if (ccb->ccb_h.status != CAM_REQ_CMP) {
1069 isp->isp_osinfo.leact[seq] = 0;
1073 tptr = get_lun_statep(isp, bus, lun);
1075 ccb->ccb_h.status = CAM_LUN_INVALID;
1081 int c, n, ulun = lun;
1083 cmd = RQSTYPE_ENABLE_LUN;
1086 if (IS_FC(isp) && lun != 0) {
1087 cmd = RQSTYPE_MODIFY_LUN;
1090 * For SCC firmware, we only deal with setting
1091 * (enabling or modifying) lun 0.
1095 if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
1096 rls_lun_statep(isp, tptr);
1097 ccb->ccb_h.status = CAM_REQ_INPROG;
1101 int c, n, ulun = lun;
1103 cmd = -RQSTYPE_MODIFY_LUN;
1106 if (IS_FC(isp) && lun != 0) {
1109 * For SCC firmware, we only deal with setting
1110 * (enabling or modifying) lun 0.
1114 if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
1115 rls_lun_statep(isp, tptr);
1116 ccb->ccb_h.status = CAM_REQ_INPROG;
1120 rls_lun_statep(isp, tptr);
1121 xpt_print(ccb->ccb_h.path, "isp_lun_cmd failed\n");
1122 isp->isp_osinfo.leact[seq] = 0;
1123 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1128 isp_ledone(ispsoftc_t *isp, lun_entry_t *lep)
1130 const char lfmt[] = "now %sabled for target mode\n";
1135 struct ccb_en_lun *cel;
1137 seq = lep->le_reserved - 1;
1138 if (seq >= NLEACT) {
1139 isp_prt(isp, ISP_LOGERR,
1140 "seq out of range (%u) in isp_ledone", seq);
1143 ccb = isp->isp_osinfo.leact[seq];
1145 isp_prt(isp, ISP_LOGERR,
1146 "no ccb for seq %u in isp_ledone", seq);
1150 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
1152 xpt_print(ccb->ccb_h.path, "null tptr in isp_ledone\n");
1153 isp->isp_osinfo.leact[seq] = 0;
1157 if (lep->le_status != LUN_OK) {
1158 xpt_print(ccb->ccb_h.path,
1159 "ENABLE/MODIFY LUN returned 0x%x\n", lep->le_status);
1161 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1162 rls_lun_statep(isp, tptr);
1163 isp->isp_osinfo.leact[seq] = 0;
1167 isp_prt(isp, ISP_LOGTDEBUG0,
1168 "isp_ledone: ENABLE/MODIFY done okay");
1173 ccb->ccb_h.status = CAM_REQ_CMP;
1174 xpt_print(ccb->ccb_h.path, lfmt, "en");
1175 rls_lun_statep(isp, tptr);
1176 isp->isp_osinfo.leact[seq] = 0;
1181 if (lep->le_header.rqs_entry_type == RQSTYPE_MODIFY_LUN) {
1182 if (isp_lun_cmd(isp, -RQSTYPE_ENABLE_LUN, XS_CHANNEL(ccb),
1183 XS_TGT(ccb), XS_LUN(ccb), 0, 0, seq+1)) {
1184 xpt_print(ccb->ccb_h.path,
1185 "isp_ledone: isp_lun_cmd failed\n");
1188 rls_lun_statep(isp, tptr);
1192 xpt_print(ccb->ccb_h.path, lfmt, "dis");
1193 rls_lun_statep(isp, tptr);
1194 destroy_lun_state(isp, tptr);
1195 ccb->ccb_h.status = CAM_REQ_CMP;
1196 isp->isp_osinfo.leact[seq] = 0;
1198 if (are_any_luns_enabled(isp, XS_CHANNEL(ccb)) == 0) {
1199 int bus = XS_CHANNEL(ccb);
1201 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
1203 isp_prt(isp, ISP_LOGWARN,
1204 "disable target mode on channel %d failed", bus);
1206 isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
1212 isp_abort_tgt_ccb(ispsoftc_t *isp, union ccb *ccb)
1215 struct ccb_hdr_slist *lp;
1216 struct ccb_hdr *curelm;
1218 union ccb *accb = ccb->cab.abort_ccb;
1220 xpt_print(ccb->ccb_h.path, "aborting ccb %p\n", accb);
1221 if (accb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
1223 if (IS_FC(isp) && (accb->ccb_h.target_id !=
1224 ((fcparam *) isp->isp_param)->isp_loopid)) {
1226 } else if (IS_SCSI(isp) && (accb->ccb_h.target_id !=
1227 ((sdparam *) isp->isp_param)->isp_initiator_id)) {
1232 * Being restrictive about target ids is really about
1233 * making sure we're aborting for the right multi-tid
1234 * path. This doesn't really make much sense at present.
1237 return (CAM_PATH_INVALID);
1241 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), accb->ccb_h.target_lun);
1243 xpt_print(ccb->ccb_h.path, "can't get statep\n");
1244 return (CAM_PATH_INVALID);
1246 if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
1248 ctr = &tptr->atio_count;
1249 } else if (accb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
1251 ctr = &tptr->inot_count;
1253 rls_lun_statep(isp, tptr);
1254 xpt_print(ccb->ccb_h.path, "bad function code %d\n",
1255 accb->ccb_h.func_code);
1256 return (CAM_UA_ABORT);
1258 curelm = SLIST_FIRST(lp);
1260 if (curelm == &accb->ccb_h) {
1262 SLIST_REMOVE_HEAD(lp, sim_links.sle);
1264 while(curelm != NULL) {
1265 struct ccb_hdr *nextelm;
1267 nextelm = SLIST_NEXT(curelm, sim_links.sle);
1268 if (nextelm == &accb->ccb_h) {
1270 SLIST_NEXT(curelm, sim_links.sle) =
1271 SLIST_NEXT(nextelm, sim_links.sle);
1277 rls_lun_statep(isp, tptr);
1280 accb->ccb_h.status = CAM_REQ_ABORTED;
1282 return (CAM_REQ_CMP);
1284 xpt_print(ccb->ccb_h.path, "ccb %p not found\n", accb);
1285 return (CAM_PATH_INVALID);
1289 isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
1292 struct ccb_scsiio *cso = &ccb->csio;
1293 uint32_t nxti, optr, handle;
1294 uint8_t local[QENTRY_LEN];
1297 if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
1298 xpt_print(ccb->ccb_h.path,
1299 "Request Queue Overflow in isp_target_start_ctio\n");
1300 XS_SETERR(ccb, CAM_REQUEUE_REQ);
1303 memset(local, 0, QENTRY_LEN);
1306 * We're either moving data or completing a command here.
1310 atio_private_data_t *atp;
1311 ct2_entry_t *cto = (ct2_entry_t *) local;
1313 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
1314 cto->ct_header.rqs_entry_count = 1;
1315 if (FCPARAM(isp)->isp_2klogin) {
1316 ((ct2e_entry_t *)cto)->ct_iid = cso->init_id;
1318 cto->ct_iid = cso->init_id;
1319 if (FCPARAM(isp)->isp_sccfw == 0) {
1320 cto->ct_lun = ccb->ccb_h.target_lun;
1324 atp = isp_get_atpd(isp, cso->tag_id);
1326 xpt_print(ccb->ccb_h.path,
1327 "cannot find private data adjunct for tag %x\n",
1329 XS_SETERR(ccb, CAM_REQ_CMP_ERR);
1333 cto->ct_rxid = cso->tag_id;
1334 if (cso->dxfer_len == 0) {
1335 cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA;
1336 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1337 cto->ct_flags |= CT2_SENDSTATUS;
1338 cto->rsp.m1.ct_scsi_status = cso->scsi_status;
1340 atp->orig_datalen - atp->bytes_xfered;
1341 if (cto->ct_resid < 0) {
1342 cto->rsp.m1.ct_scsi_status |=
1344 } else if (cto->ct_resid > 0) {
1345 cto->rsp.m1.ct_scsi_status |=
1349 if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) {
1350 int m = min(cso->sense_len, MAXRESPLEN);
1351 memcpy(cto->rsp.m1.ct_resp,
1352 &cso->sense_data, m);
1353 cto->rsp.m1.ct_senselen = m;
1354 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
1357 cto->ct_flags |= CT2_FLAG_MODE0;
1358 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1359 cto->ct_flags |= CT2_DATA_IN;
1361 cto->ct_flags |= CT2_DATA_OUT;
1363 cto->ct_reloff = atp->bytes_xfered;
1364 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
1365 cto->ct_flags |= CT2_SENDSTATUS;
1366 cto->rsp.m0.ct_scsi_status = cso->scsi_status;
1369 (atp->bytes_xfered + cso->dxfer_len);
1370 if (cto->ct_resid < 0) {
1371 cto->rsp.m0.ct_scsi_status |=
1373 } else if (cto->ct_resid > 0) {
1374 cto->rsp.m0.ct_scsi_status |=
1378 atp->last_xframt = cso->dxfer_len;
1381 * If we're sending data and status back together,
1382 * we can't also send back sense data as well.
1384 ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1387 if (cto->ct_flags & CT2_SENDSTATUS) {
1388 isp_prt(isp, ISP_LOGTDEBUG0,
1389 "CTIO2[%x] STATUS %x origd %u curd %u resid %u",
1390 cto->ct_rxid, cso->scsi_status, atp->orig_datalen,
1391 cso->dxfer_len, cto->ct_resid);
1392 cto->ct_flags |= CT2_CCINCR;
1393 atp->state = ATPD_STATE_LAST_CTIO;
1395 atp->state = ATPD_STATE_CTIO;
1397 cto->ct_timeout = 10;
1399 ct_entry_t *cto = (ct_entry_t *) local;
1401 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
1402 cto->ct_header.rqs_entry_count = 1;
1403 cto->ct_iid = cso->init_id;
1404 cto->ct_iid |= XS_CHANNEL(ccb) << 7;
1405 cto->ct_tgt = ccb->ccb_h.target_id;
1406 cto->ct_lun = ccb->ccb_h.target_lun;
1407 cto->ct_fwhandle = AT_GET_HANDLE(cso->tag_id);
1408 if (AT_HAS_TAG(cso->tag_id)) {
1409 cto->ct_tag_val = (uint8_t) AT_GET_TAG(cso->tag_id);
1410 cto->ct_flags |= CT_TQAE;
1412 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) {
1413 cto->ct_flags |= CT_NODISC;
1415 if (cso->dxfer_len == 0) {
1416 cto->ct_flags |= CT_NO_DATA;
1417 } else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1418 cto->ct_flags |= CT_DATA_IN;
1420 cto->ct_flags |= CT_DATA_OUT;
1422 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1423 cto->ct_flags |= CT_SENDSTATUS|CT_CCINCR;
1424 cto->ct_scsi_status = cso->scsi_status;
1425 cto->ct_resid = cso->resid;
1426 isp_prt(isp, ISP_LOGTDEBUG0,
1427 "CTIO[%x] SCSI STATUS 0x%x resid %d tag_id %x",
1428 cto->ct_fwhandle, cso->scsi_status, cso->resid,
1431 ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1432 cto->ct_timeout = 10;
1435 if (isp_save_xs_tgt(isp, ccb, &handle)) {
1436 xpt_print(ccb->ccb_h.path,
1437 "No XFLIST pointers for isp_target_start_ctio\n");
1438 XS_SETERR(ccb, CAM_REQUEUE_REQ);
1444 * Call the dma setup routines for this entry (and any subsequent
1445 * CTIOs) if there's data to move, and then tell the f/w it's got
1446 * new things to play with. As with isp_start's usage of DMA setup,
1447 * any swizzling is done in the machine dependent layer. Because
1448 * of this, we put the request onto the queue area first in native
1453 ct2_entry_t *cto = (ct2_entry_t *) local;
1454 cto->ct_syshandle = handle;
1456 ct_entry_t *cto = (ct_entry_t *) local;
1457 cto->ct_syshandle = handle;
1460 switch (ISP_DMASETUP(isp, cso, (ispreq_t *) local, &nxti, optr)) {
1462 ISP_ADD_REQUEST(isp, nxti);
1463 ccb->ccb_h.status |= CAM_SIM_QUEUED;
1467 XS_SETERR(ccb, CAM_REQUEUE_REQ);
1473 isp_destroy_tgt_handle(isp, handle);
1480 isp_refire_putback_atio(void *arg)
1483 isp_target_putback_atio(arg);
1488 isp_target_putback_atio(union ccb *ccb)
1491 struct ccb_scsiio *cso;
1492 uint32_t nxti, optr;
1497 if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
1498 xpt_print(ccb->ccb_h.path,
1499 "isp_target_putback_atio: Request Queue Overflow\n");
1500 (void) timeout(isp_refire_putback_atio, ccb, 10);
1503 memset(qe, 0, QENTRY_LEN);
1506 at2_entry_t local, *at = &local;
1507 MEMZERO(at, sizeof (at2_entry_t));
1508 at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
1509 at->at_header.rqs_entry_count = 1;
1510 if (FCPARAM(isp)->isp_sccfw) {
1511 at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
1513 at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
1515 at->at_status = CT_OK;
1516 at->at_rxid = cso->tag_id;
1517 at->at_iid = cso->ccb_h.target_id;
1518 isp_put_atio2(isp, at, qe);
1520 at_entry_t local, *at = &local;
1521 MEMZERO(at, sizeof (at_entry_t));
1522 at->at_header.rqs_entry_type = RQSTYPE_ATIO;
1523 at->at_header.rqs_entry_count = 1;
1524 at->at_iid = cso->init_id;
1525 at->at_iid |= XS_CHANNEL(ccb) << 7;
1526 at->at_tgt = cso->ccb_h.target_id;
1527 at->at_lun = cso->ccb_h.target_lun;
1528 at->at_status = CT_OK;
1529 at->at_tag_val = AT_GET_TAG(cso->tag_id);
1530 at->at_handle = AT_GET_HANDLE(cso->tag_id);
1531 isp_put_atio(isp, at, qe);
1533 ISP_TDQE(isp, "isp_target_putback_atio", (int) optr, qe);
1534 ISP_ADD_REQUEST(isp, nxti);
1535 isp_complete_ctio(ccb);
1539 isp_complete_ctio(union ccb *ccb)
1541 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
1542 ccb->ccb_h.status |= CAM_REQ_CMP;
1544 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1549 * Handle ATIO stuff that the generic code can't.
1550 * This means handling CDBs.
1554 isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep)
1557 int status, bus, iswildcard;
1558 struct ccb_accept_tio *atiop;
1561 * The firmware status (except for the QLTM_SVALID bit)
1562 * indicates why this ATIO was sent to us.
1564 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1566 * If the DISCONNECTS DISABLED bit is set in the flags field,
1567 * we're still connected on the SCSI bus.
1569 status = aep->at_status;
1570 if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
1572 * Bus Phase Sequence error. We should have sense data
1573 * suggested by the f/w. I'm not sure quite yet what
1574 * to do about this for CAM.
1576 isp_prt(isp, ISP_LOGWARN, "PHASE ERROR");
1577 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1580 if ((status & ~QLTM_SVALID) != AT_CDB) {
1581 isp_prt(isp, ISP_LOGWARN, "bad atio (0x%x) leaked to platform",
1583 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1587 bus = GET_BUS_VAL(aep->at_iid);
1588 tptr = get_lun_statep(isp, bus, aep->at_lun);
1590 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
1593 * Because we can't autofeed sense data back with
1594 * a command for parallel SCSI, we can't give back
1595 * a CHECK CONDITION. We'll give back a BUSY status
1596 * instead. This works out okay because the only
1597 * time we should, in fact, get this, is in the
1598 * case that somebody configured us without the
1599 * blackhole driver, so they get what they deserve.
1601 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1609 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1610 if (atiop == NULL) {
1612 * Because we can't autofeed sense data back with
1613 * a command for parallel SCSI, we can't give back
1614 * a CHECK CONDITION. We'll give back a QUEUE FULL status
1615 * instead. This works out okay because the only time we
1616 * should, in fact, get this, is in the case that we've
1619 xpt_print(tptr->owner,
1620 "no ATIOS for lun %d from initiator %d on channel %d\n",
1621 aep->at_lun, GET_IID_VAL(aep->at_iid), bus);
1622 if (aep->at_flags & AT_TQAE)
1623 isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1625 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1626 rls_lun_statep(isp, tptr);
1629 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1631 isp_prt(isp, ISP_LOGTDEBUG0, "Take FREE ATIO lun %d, count now %d",
1632 aep->at_lun, tptr->atio_count);
1634 atiop->ccb_h.target_id = aep->at_tgt;
1635 atiop->ccb_h.target_lun = aep->at_lun;
1637 if (aep->at_flags & AT_NODISC) {
1638 atiop->ccb_h.flags = CAM_DIS_DISCONNECT;
1640 atiop->ccb_h.flags = 0;
1643 if (status & QLTM_SVALID) {
1644 size_t amt = imin(QLTM_SENSELEN, sizeof (atiop->sense_data));
1645 atiop->sense_len = amt;
1646 MEMCPY(&atiop->sense_data, aep->at_sense, amt);
1648 atiop->sense_len = 0;
1651 atiop->init_id = GET_IID_VAL(aep->at_iid);
1652 atiop->cdb_len = aep->at_cdblen;
1653 MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
1654 atiop->ccb_h.status = CAM_CDB_RECVD;
1656 * Construct a tag 'id' based upon tag value (which may be 0..255)
1657 * and the handle (which we have to preserve).
1659 AT_MAKE_TAGID(atiop->tag_id, bus, device_get_unit(isp->isp_dev), aep);
1660 if (aep->at_flags & AT_TQAE) {
1661 atiop->tag_action = aep->at_tag_type;
1662 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
1664 xpt_done((union ccb*)atiop);
1665 isp_prt(isp, ISP_LOGTDEBUG0,
1666 "ATIO[%x] CDB=0x%x bus %d iid%d->lun%d tag 0x%x ttype 0x%x %s",
1667 aep->at_handle, aep->at_cdb[0] & 0xff, GET_BUS_VAL(aep->at_iid),
1668 GET_IID_VAL(aep->at_iid), aep->at_lun, aep->at_tag_val & 0xff,
1669 aep->at_tag_type, (aep->at_flags & AT_NODISC)?
1670 "nondisc" : "disconnecting");
1671 rls_lun_statep(isp, tptr);
1676 isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1680 struct ccb_accept_tio *atiop;
1681 atio_private_data_t *atp;
1684 * The firmware status (except for the QLTM_SVALID bit)
1685 * indicates why this ATIO was sent to us.
1687 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1689 if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
1690 isp_prt(isp, ISP_LOGWARN,
1691 "bogus atio (0x%x) leaked to platform", aep->at_status);
1692 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1696 if (FCPARAM(isp)->isp_sccfw) {
1697 lun = aep->at_scclun;
1701 tptr = get_lun_statep(isp, 0, lun);
1703 isp_prt(isp, ISP_LOGTDEBUG0,
1704 "[0x%x] no state pointer for lun %d", aep->at_rxid, lun);
1705 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
1707 isp_endcmd(isp, aep,
1708 SCSI_STATUS_CHECK_COND | ECMD_SVALID |
1709 (0x5 << 12) | (0x25 << 16), 0);
1714 atp = isp_get_atpd(isp, 0);
1715 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1716 if (atiop == NULL || atp == NULL) {
1719 * Because we can't autofeed sense data back with
1720 * a command for parallel SCSI, we can't give back
1721 * a CHECK CONDITION. We'll give back a QUEUE FULL status
1722 * instead. This works out okay because the only time we
1723 * should, in fact, get this, is in the case that we've
1726 xpt_print(tptr->owner,
1727 "no %s for lun %d from initiator %d\n",
1728 (atp == NULL && atiop == NULL)? "ATIO2s *or* ATPS" :
1729 ((atp == NULL)? "ATPs" : "ATIO2s"), lun, aep->at_iid);
1730 rls_lun_statep(isp, tptr);
1731 isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1734 atp->state = ATPD_STATE_ATIO;
1735 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1737 isp_prt(isp, ISP_LOGTDEBUG0, "Take FREE ATIO lun %d, count now %d",
1738 lun, tptr->atio_count);
1740 if (tptr == &isp->isp_osinfo.tsdflt[0]) {
1741 atiop->ccb_h.target_id = FCPARAM(isp)->isp_loopid;
1742 atiop->ccb_h.target_lun = lun;
1745 * We don't get 'suggested' sense data as we do with SCSI cards.
1747 atiop->sense_len = 0;
1749 atiop->init_id = aep->at_iid;
1750 atiop->cdb_len = ATIO2_CDBLEN;
1751 MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
1752 atiop->ccb_h.status = CAM_CDB_RECVD;
1753 atiop->tag_id = aep->at_rxid;
1754 switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
1755 case ATIO2_TC_ATTR_SIMPLEQ:
1756 atiop->tag_action = MSG_SIMPLE_Q_TAG;
1758 case ATIO2_TC_ATTR_HEADOFQ:
1759 atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1761 case ATIO2_TC_ATTR_ORDERED:
1762 atiop->tag_action = MSG_ORDERED_Q_TAG;
1764 case ATIO2_TC_ATTR_ACAQ: /* ?? */
1765 case ATIO2_TC_ATTR_UNTAGGED:
1767 atiop->tag_action = 0;
1770 atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
1772 atp->tag = atiop->tag_id;
1774 atp->orig_datalen = aep->at_datalen;
1775 atp->last_xframt = 0;
1776 atp->bytes_xfered = 0;
1777 atp->state = ATPD_STATE_CAM;
1778 xpt_done((union ccb*)atiop);
1780 isp_prt(isp, ISP_LOGTDEBUG0,
1781 "ATIO2[%x] CDB=0x%x iid%d->lun%d tattr 0x%x datalen %u",
1782 aep->at_rxid, aep->at_cdb[0] & 0xff, aep->at_iid,
1783 lun, aep->at_taskflags, aep->at_datalen);
1784 rls_lun_statep(isp, tptr);
1789 isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
1792 int sentstatus, ok, notify_cam, resid = 0;
1796 * CTIO and CTIO2 are close enough....
1799 ccb = isp_find_xs_tgt(isp, ((ct_entry_t *)arg)->ct_syshandle);
1800 KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio"));
1801 isp_destroy_tgt_handle(isp, ((ct_entry_t *)arg)->ct_syshandle);
1804 ct2_entry_t *ct = arg;
1805 atio_private_data_t *atp = isp_get_atpd(isp, ct->ct_rxid);
1807 isp_prt(isp, ISP_LOGERR,
1808 "cannot find adjunct for %x after I/O",
1812 sentstatus = ct->ct_flags & CT2_SENDSTATUS;
1813 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
1814 if (ok && sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) {
1815 ccb->ccb_h.status |= CAM_SENT_SENSE;
1817 notify_cam = ct->ct_header.rqs_seqno & 0x1;
1818 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1819 resid = ct->ct_resid;
1820 atp->bytes_xfered += (atp->last_xframt - resid);
1821 atp->last_xframt = 0;
1823 if (sentstatus || !ok) {
1826 isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN,
1827 "CTIO2[%x] sts 0x%x flg 0x%x sns %d resid %d %s",
1828 ct->ct_rxid, ct->ct_status, ct->ct_flags,
1829 (ccb->ccb_h.status & CAM_SENT_SENSE) != 0,
1830 resid, sentstatus? "FIN" : "MID");
1833 /* XXX: should really come after isp_complete_ctio */
1834 atp->state = ATPD_STATE_PDON;
1836 ct_entry_t *ct = arg;
1837 sentstatus = ct->ct_flags & CT_SENDSTATUS;
1838 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
1840 * We *ought* to be able to get back to the original ATIO
1841 * here, but for some reason this gets lost. It's just as
1842 * well because it's squirrelled away as part of periph
1845 * We can live without it as long as we continue to use
1846 * the auto-replenish feature for CTIOs.
1848 notify_cam = ct->ct_header.rqs_seqno & 0x1;
1849 if (ct->ct_status & QLTM_SVALID) {
1850 char *sp = (char *)ct;
1851 sp += CTIO_SENSE_OFFSET;
1852 ccb->csio.sense_len =
1853 min(sizeof (ccb->csio.sense_data), QLTM_SENSELEN);
1854 MEMCPY(&ccb->csio.sense_data, sp, ccb->csio.sense_len);
1855 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
1857 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1858 resid = ct->ct_resid;
1860 isp_prt(isp, ISP_LOGTDEBUG0,
1861 "CTIO[%x] tag %x iid %d lun %d sts %x flg %x resid %d %s",
1862 ct->ct_fwhandle, ct->ct_tag_val, ct->ct_iid, ct->ct_lun,
1863 ct->ct_status, ct->ct_flags, resid,
1864 sentstatus? "FIN" : "MID");
1865 tval = ct->ct_fwhandle;
1867 ccb->csio.resid += resid;
1870 * We're here either because intermediate data transfers are done
1871 * and/or the final status CTIO (which may have joined with a
1872 * Data Transfer) is done.
1874 * In any case, for this platform, the upper layers figure out
1875 * what to do next, so all we do here is collect status and
1876 * pass information along. Any DMA handles have already been
1879 if (notify_cam == 0) {
1880 isp_prt(isp, ISP_LOGTDEBUG0, " INTER CTIO[0x%x] done", tval);
1884 isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done",
1885 (sentstatus)? " FINAL " : "MIDTERM ", tval);
1888 isp_target_putback_atio(ccb);
1890 isp_complete_ctio(ccb);
1897 isp_handle_platform_notify_scsi(ispsoftc_t *isp, in_entry_t *inp)
1899 return (0); /* XXXX */
1903 isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
1906 switch (inp->in_status) {
1907 case IN_PORT_LOGOUT:
1908 isp_prt(isp, ISP_LOGWARN, "port logout of iid %d",
1911 case IN_PORT_CHANGED:
1912 isp_prt(isp, ISP_LOGWARN, "port changed for iid %d",
1915 case IN_GLOBAL_LOGO:
1916 isp_prt(isp, ISP_LOGINFO, "all ports logged out");
1920 atio_private_data_t *atp = isp_get_atpd(isp, inp->in_seqid);
1921 struct ccb_immed_notify *inot = NULL;
1924 tstate_t *tptr = get_lun_statep(isp, 0, atp->lun);
1926 inot = (struct ccb_immed_notify *)
1927 SLIST_FIRST(&tptr->inots);
1930 SLIST_REMOVE_HEAD(&tptr->inots,
1932 isp_prt(isp, ISP_LOGTDEBUG0,
1933 "Take FREE INOT count now %d",
1937 isp_prt(isp, ISP_LOGWARN,
1938 "abort task RX_ID %x IID %d state %d",
1939 inp->in_seqid, inp->in_iid, atp->state);
1941 isp_prt(isp, ISP_LOGWARN,
1942 "abort task RX_ID %x from iid %d, state unknown",
1943 inp->in_seqid, inp->in_iid);
1946 inot->initiator_id = inp->in_iid;
1947 inot->sense_len = 0;
1948 inot->message_args[0] = MSG_ABORT_TAG;
1949 inot->message_args[1] = inp->in_seqid & 0xff;
1950 inot->message_args[2] = (inp->in_seqid >> 8) & 0xff;
1951 inot->ccb_h.status = CAM_MESSAGE_RECV;
1952 xpt_done((union ccb *)inot);
1964 isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
1966 struct cam_sim *sim;
1969 sim = (struct cam_sim *)cbarg;
1970 isp = (ispsoftc_t *) cam_sim_softc(sim);
1972 case AC_LOST_DEVICE:
1974 uint16_t oflags, nflags;
1975 sdparam *sdp = isp->isp_param;
1978 tgt = xpt_path_target_id(path);
1980 sdp += cam_sim_bus(sim);
1981 nflags = sdp->isp_devparam[tgt].nvrm_flags;
1982 #ifndef ISP_TARGET_MODE
1983 nflags &= DPARM_SAFE_DFLT;
1984 if (isp->isp_loaded_fw) {
1985 nflags |= DPARM_NARROW | DPARM_ASYNC;
1988 nflags = DPARM_DEFAULT;
1990 oflags = sdp->isp_devparam[tgt].goal_flags;
1991 sdp->isp_devparam[tgt].goal_flags = nflags;
1992 sdp->isp_devparam[tgt].dev_update = 1;
1993 isp->isp_update |= (1 << cam_sim_bus(sim));
1994 (void) isp_control(isp,
1995 ISPCTL_UPDATE_PARAMS, NULL);
1996 sdp->isp_devparam[tgt].goal_flags = oflags;
2001 isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code);
2007 isp_poll(struct cam_sim *sim)
2009 ispsoftc_t *isp = cam_sim_softc(sim);
2011 uint16_t sema, mbox;
2013 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
2014 isp_intr(isp, isr, sema, mbox);
2019 static int isp_watchdog_work(ispsoftc_t *, XS_T *);
2022 isp_watchdog_work(ispsoftc_t *isp, XS_T *xs)
2027 * We've decided this command is dead. Make sure we're not trying
2028 * to kill a command that's already dead by getting it's handle and
2029 * and seeing whether it's still alive.
2031 handle = isp_find_handle(isp, xs);
2034 uint16_t sema, mbox;
2036 if (XS_CMD_DONE_P(xs)) {
2037 isp_prt(isp, ISP_LOGDEBUG1,
2038 "watchdog found done cmd (handle 0x%x)", handle);
2042 if (XS_CMD_WDOG_P(xs)) {
2043 isp_prt(isp, ISP_LOGDEBUG2,
2044 "recursive watchdog (handle 0x%x)", handle);
2049 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
2050 isp_intr(isp, isr, sema, mbox);
2052 if (XS_CMD_DONE_P(xs)) {
2053 isp_prt(isp, ISP_LOGDEBUG2,
2054 "watchdog cleanup for handle 0x%x", handle);
2055 isp_free_pcmd(isp, (union ccb *)xs);
2056 xpt_done((union ccb *) xs);
2057 } else if (XS_CMD_GRACE_P(xs)) {
2059 * Make sure the command is *really* dead before we
2060 * release the handle (and DMA resources) for reuse.
2062 (void) isp_control(isp, ISPCTL_ABORT_CMD, xs);
2065 * After this point, the comamnd is really dead.
2067 if (XS_XFRLEN(xs)) {
2068 ISP_DMAFREE(isp, xs, handle);
2070 isp_destroy_handle(isp, handle);
2071 xpt_print(xs->ccb_h.path,
2072 "watchdog timeout for handle 0x%x\n", handle);
2073 XS_SETERR(xs, CAM_CMD_TIMEOUT);
2078 xs->ccb_h.timeout_ch = timeout(isp_watchdog, xs, hz);
2080 isp->isp_sendmarker |= 1 << XS_CHANNEL(xs);
2088 isp_watchdog(void *arg)
2094 for (r = 0, isp = isplist; r && isp; isp = isp->isp_osinfo.next) {
2096 r = isp_watchdog_work(isp, xs);
2100 printf("isp_watchdog: nobody had %p active\n", arg);
2105 #if __FreeBSD_version >= 600000
2107 isp_make_here(ispsoftc_t *isp, int tgt)
2111 * Allocate a CCB, create a wildcard path for this bus,
2112 * and schedule a rescan.
2114 ccb = xpt_alloc_ccb_nowait();
2116 isp_prt(isp, ISP_LOGWARN, "unable to alloc CCB for rescan");
2119 if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
2120 cam_sim_path(isp->isp_sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2121 isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
2129 isp_make_gone(ispsoftc_t *isp, int tgt)
2131 struct cam_path *tp;
2132 if (xpt_create_path(&tp, NULL, cam_sim_path(isp->isp_sim), tgt,
2133 CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
2134 xpt_async(AC_LOST_DEVICE, tp, NULL);
2139 #define isp_make_here(isp, tgt) do { ; } while (0)
2140 #define isp_make_gone(isp, tgt) do { ; } while (0)
2145 * Gone Device Timer Function- when we have decided that a device has gone
2146 * away, we wait a specific period of time prior to telling the OS it has
2149 * This timer function fires once a second and then scans the port database
2150 * for devices that are marked dead but still have a virtual target assigned.
2151 * We decrement a counter for that port database entry, and when it hits zero,
2152 * we tell the OS the device has gone away.
2157 ispsoftc_t *isp = arg;
2159 int dbidx, tgt, more_to_do = 0;
2162 isp_prt(isp, ISP_LOGDEBUG0, "GDT timer expired");
2163 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2164 lp = &FCPARAM(isp)->portdb[dbidx];
2166 if (lp->state != FC_PORTDB_STATE_ZOMBIE) {
2169 if (lp->ini_map_idx == 0) {
2172 if (lp->new_reserved == 0) {
2175 lp->new_reserved -= 1;
2176 if (lp->new_reserved != 0) {
2180 tgt = lp->ini_map_idx - 1;
2181 FCPARAM(isp)->isp_ini_map[tgt] = 0;
2182 lp->ini_map_idx = 0;
2183 lp->state = FC_PORTDB_STATE_NIL;
2184 isp_prt(isp, ISP_LOGCONFIG, prom3, lp->portid, tgt,
2185 "Gone Device Timeout");
2186 isp_make_gone(isp, tgt);
2189 isp->isp_osinfo.gdt_running = 1;
2190 callout_reset(&isp->isp_osinfo.gdt, hz, isp_gdt, isp);
2192 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2193 "stopping Gone Device Timer");
2194 isp->isp_osinfo.gdt_running = 0;
2200 * Loop Down Timer Function- when loop goes down, a timer is started and
2201 * and after it expires we come here and take all probational devices that
2202 * the OS knows about and the tell the OS that they've gone away.
2204 * We don't clear the devices out of our port database because, when loop
2205 * come back up, we have to do some actual cleanup with the chip at that
2206 * point (implicit PLOGO, e.g., to get the chip's port database state right).
2211 ispsoftc_t *isp = arg;
2217 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Loop Down Timer expired");
2220 * Notify to the OS all targets who we now consider have departed.
2222 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2223 lp = &FCPARAM(isp)->portdb[dbidx];
2225 if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
2228 if (lp->ini_map_idx == 0) {
2233 * XXX: CLEAN UP AND COMPLETE ANY PENDING COMMANDS FIRST!
2237 * Mark that we've announced that this device is gone....
2242 * but *don't* change the state of the entry. Just clear
2243 * any target id stuff and announce to CAM that the
2244 * device is gone. This way any necessary PLOGO stuff
2245 * will happen when loop comes back up.
2248 tgt = lp->ini_map_idx - 1;
2249 FCPARAM(isp)->isp_ini_map[tgt] = 0;
2250 lp->ini_map_idx = 0;
2251 isp_prt(isp, ISP_LOGCONFIG, prom3, lp->portid, tgt,
2252 "Loop Down Timeout");
2253 isp_make_gone(isp, tgt);
2257 * The loop down timer has expired. Wake up the kthread
2258 * to notice that fact (or make it false).
2260 isp->isp_osinfo.loop_down_time = isp->isp_osinfo.loop_down_limit+1;
2261 wakeup(ISP_KT_WCHAN(isp));
2266 isp_kthread(void *arg)
2268 ispsoftc_t *isp = arg;
2270 #if __FreeBSD_version < 500000
2272 #elif __FreeBSD_version < 700037
2275 mtx_lock(&isp->isp_osinfo.lock);
2278 * The first loop is for our usage where we have yet to have
2279 * gotten good fibre channel state.
2282 int wasfrozen, lb, lim;
2284 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2285 "isp_kthread: checking FC state");
2286 isp->isp_osinfo.mbox_sleep_ok = 1;
2287 lb = isp_fc_runstate(isp, 250000);
2288 isp->isp_osinfo.mbox_sleep_ok = 0;
2291 * Increment loop down time by the last sleep interval
2293 isp->isp_osinfo.loop_down_time += slp;
2296 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2297 "kthread: FC loop not up (down count %d)",
2298 isp->isp_osinfo.loop_down_time);
2300 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2301 "kthread: FC got to %d (down count %d)",
2302 lb, isp->isp_osinfo.loop_down_time);
2307 * If we've never seen loop up and we've waited longer
2308 * than quickboot time, or we've seen loop up but we've
2309 * waited longer than loop_down_limit, give up and go
2310 * to sleep until loop comes up.
2312 if (FCPARAM(isp)->loop_seen_once == 0) {
2313 lim = isp_quickboot_time;
2315 lim = isp->isp_osinfo.loop_down_limit;
2317 if (isp->isp_osinfo.loop_down_time >= lim) {
2318 isp_freeze_loopdown(isp, "loop limit hit");
2320 } else if (isp->isp_osinfo.loop_down_time < 10) {
2322 } else if (isp->isp_osinfo.loop_down_time < 30) {
2324 } else if (isp->isp_osinfo.loop_down_time < 60) {
2326 } else if (isp->isp_osinfo.loop_down_time < 120) {
2333 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2334 "isp_kthread: FC state OK");
2335 isp->isp_osinfo.loop_down_time = 0;
2340 * If we'd frozen the simq, unfreeze it now so that CAM
2341 * can start sending us commands. If the FC state isn't
2342 * okay yet, they'll hit that in isp_start which will
2343 * freeze the queue again.
2345 wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
2346 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
2347 if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
2348 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2349 "isp_kthread: releasing simq");
2350 xpt_release_simq(isp->isp_sim, 1);
2352 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2353 "isp_kthread: sleep time %d", slp);
2354 #if __FreeBSD_version < 700037
2355 tsleep(ISP_KT_WCHAN(isp), PRIBIO, "ispf", slp * hz);
2357 msleep(ISP_KT_WCHAN(isp), &isp->isp_osinfo.lock,
2358 PRIBIO, "ispf", slp * hz);
2361 * If slp is zero, we're waking up for the first time after
2362 * things have been okay. In this case, we set a deferral state
2363 * for all commands and delay hysteresis seconds before starting
2364 * the FC state evaluation. This gives the loop/fabric a chance
2367 if (slp == 0 && isp->isp_osinfo.hysteresis) {
2368 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2369 "isp_kthread: sleep hysteresis tick time %d",
2370 isp->isp_osinfo.hysteresis * hz);
2371 #if __FreeBSD_version < 700037
2372 (void) tsleep(&isp_fabric_hysteresis, PRIBIO, "ispT",
2373 (isp->isp_osinfo.hysteresis * hz));
2375 (void) msleep(&isp_fabric_hysteresis,
2376 &isp->isp_osinfo.lock, PRIBIO, "ispT",
2377 (isp->isp_osinfo.hysteresis * hz));
2381 #if __FreeBSD_version < 500000
2383 #elif __FreeBSD_version < 700037
2386 mtx_unlock(&isp->isp_osinfo.lock);
2390 #if __FreeBSD_version < 500000
2391 static void isp_action_wrk(struct cam_sim *, union ccb *);
2393 isp_action(struct cam_sim *sim, union ccb *ccb)
2395 ispsoftc_t *isp = (ispsoftc_t *)cam_sim_softc(sim);
2397 isp_action_wrk(sim, ccb);
2400 #define isp_action isp_action_wrk
2404 isp_action(struct cam_sim *sim, union ccb *ccb)
2406 int bus, tgt, ts, error, lim;
2408 struct ccb_trans_settings *cts;
2410 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
2412 isp = (ispsoftc_t *)cam_sim_softc(sim);
2413 if (isp->isp_state != ISP_RUNSTATE &&
2414 ccb->ccb_h.func_code == XPT_SCSI_IO) {
2416 if (isp->isp_state != ISP_INITSTATE) {
2418 * Lie. Say it was a selection timeout.
2420 ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
2421 xpt_freeze_devq(ccb->ccb_h.path, 1);
2425 isp->isp_state = ISP_RUNSTATE;
2427 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
2428 ISP_PCMD(ccb) = NULL;
2430 switch (ccb->ccb_h.func_code) {
2431 case XPT_SCSI_IO: /* Execute the requested I/O operation */
2433 * Do a couple of preliminary checks...
2435 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
2436 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
2437 ccb->ccb_h.status = CAM_REQ_INVALID;
2443 if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) {
2444 xpt_print(ccb->ccb_h.path, "invalid target\n");
2445 ccb->ccb_h.status = CAM_PATH_INVALID;
2446 } else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) {
2447 xpt_print(ccb->ccb_h.path, "invalid lun\n");
2448 ccb->ccb_h.status = CAM_PATH_INVALID;
2450 if (ccb->ccb_h.status == CAM_PATH_INVALID) {
2455 ccb->csio.scsi_status = SCSI_STATUS_OK;
2456 if (isp_get_pcmd(isp, ccb)) {
2457 isp_prt(isp, ISP_LOGWARN, "out of PCMDs");
2458 cam_freeze_devq(ccb->ccb_h.path);
2459 cam_release_devq(ccb->ccb_h.path,
2460 RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
2464 error = isp_start((XS_T *) ccb);
2467 XS_CMD_S_CLEAR(ccb);
2468 ccb->ccb_h.status |= CAM_SIM_QUEUED;
2469 if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
2472 ts = ccb->ccb_h.timeout;
2473 if (ts == CAM_TIME_DEFAULT) {
2476 ts = isp_mstohz(ts);
2477 callout_reset(&PISP_PCMD(ccb)->wdog, ts,
2482 * Handle initial and subsequent loop down cases
2484 if (FCPARAM(isp)->loop_seen_once == 0) {
2485 lim = isp_quickboot_time;
2487 lim = isp->isp_osinfo.loop_down_limit;
2489 if (isp->isp_osinfo.loop_down_time >= lim) {
2490 isp_prt(isp, ISP_LOGDEBUG0,
2491 "%d.%d downtime (%d) > lim (%d)",
2492 XS_TGT(ccb), XS_LUN(ccb),
2493 isp->isp_osinfo.loop_down_time, lim);
2495 CAM_SEL_TIMEOUT|CAM_DEV_QFRZN;
2496 xpt_freeze_devq(ccb->ccb_h.path, 1);
2497 isp_free_pcmd(isp, ccb);
2501 isp_prt(isp, ISP_LOGDEBUG0,
2502 "%d.%d retry later", XS_TGT(ccb), XS_LUN(ccb));
2504 * Otherwise, retry in a while.
2506 cam_freeze_devq(ccb->ccb_h.path);
2507 cam_release_devq(ccb->ccb_h.path,
2508 RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
2509 XS_SETERR(ccb, CAM_REQUEUE_REQ);
2510 isp_free_pcmd(isp, ccb);
2514 XS_SETERR(ccb, CAM_REQUEUE_REQ);
2515 isp_free_pcmd(isp, ccb);
2519 isp_done((struct ccb_scsiio *) ccb);
2522 isp_prt(isp, ISP_LOGERR,
2523 "What's this? 0x%x at %d in file %s",
2524 error, __LINE__, __FILE__);
2525 XS_SETERR(ccb, CAM_REQ_CMP_ERR);
2526 isp_free_pcmd(isp, ccb);
2531 #ifdef ISP_TARGET_MODE
2532 case XPT_EN_LUN: /* Enable LUN as a target */
2535 seq = isp_en_lun(isp, ccb);
2540 for (i = 0; isp->isp_osinfo.leact[seq] && i < 30 * 1000; i++) {
2542 uint16_t sema, mbox;
2543 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
2544 isp_intr(isp, isr, sema, mbox);
2550 case XPT_NOTIFY_ACK: /* recycle notify ack */
2551 case XPT_IMMED_NOTIFY: /* Add Immediate Notify Resource */
2552 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */
2555 get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
2557 ccb->ccb_h.status = CAM_LUN_INVALID;
2561 ccb->ccb_h.sim_priv.entries[0].field = 0;
2562 ccb->ccb_h.sim_priv.entries[1].ptr = isp;
2563 ccb->ccb_h.flags = 0;
2565 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
2567 * Note that the command itself may not be done-
2568 * it may not even have had the first CTIO sent.
2571 isp_prt(isp, ISP_LOGTDEBUG0,
2572 "Put FREE ATIO, lun %d, count now %d",
2573 ccb->ccb_h.target_lun, tptr->atio_count);
2574 SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h,
2576 } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
2578 isp_prt(isp, ISP_LOGTDEBUG0,
2579 "Put FREE INOT, lun %d, count now %d",
2580 ccb->ccb_h.target_lun, tptr->inot_count);
2581 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h,
2584 isp_prt(isp, ISP_LOGWARN, "Got Notify ACK");;
2586 rls_lun_statep(isp, tptr);
2587 ccb->ccb_h.status = CAM_REQ_INPROG;
2590 case XPT_CONT_TARGET_IO:
2592 isp_target_start_ctio(isp, ccb);
2596 case XPT_RESET_DEV: /* BDR the specified SCSI device */
2598 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
2599 tgt = ccb->ccb_h.target_id;
2602 error = isp_control(isp, ISPCTL_RESET_DEV, &tgt);
2604 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2606 ccb->ccb_h.status = CAM_REQ_CMP;
2610 case XPT_ABORT: /* Abort the specified CCB */
2612 union ccb *accb = ccb->cab.abort_ccb;
2613 switch (accb->ccb_h.func_code) {
2614 #ifdef ISP_TARGET_MODE
2615 case XPT_ACCEPT_TARGET_IO:
2616 case XPT_IMMED_NOTIFY:
2617 ccb->ccb_h.status = isp_abort_tgt_ccb(isp, ccb);
2619 case XPT_CONT_TARGET_IO:
2620 isp_prt(isp, ISP_LOGERR, "cannot abort CTIOs yet");
2621 ccb->ccb_h.status = CAM_UA_ABORT;
2625 error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
2627 ccb->ccb_h.status = CAM_UA_ABORT;
2629 ccb->ccb_h.status = CAM_REQ_CMP;
2633 ccb->ccb_h.status = CAM_REQ_INVALID;
2639 #ifdef CAM_NEW_TRAN_CODE
2640 #define IS_CURRENT_SETTINGS(c) (c->type == CTS_TYPE_CURRENT_SETTINGS)
2642 #define IS_CURRENT_SETTINGS(c) (c->flags & CCB_TRANS_CURRENT_SETTINGS)
2644 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */
2646 if (!IS_CURRENT_SETTINGS(cts)) {
2647 ccb->ccb_h.status = CAM_REQ_INVALID;
2651 tgt = cts->ccb_h.target_id;
2653 #ifndef CAM_NEW_TRAN_CODE
2654 sdparam *sdp = isp->isp_param;
2657 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2661 * We always update (internally) from goal_flags
2662 * so any request to change settings just gets
2663 * vectored to that location.
2665 dptr = &sdp->isp_devparam[tgt].goal_flags;
2668 * Note that these operations affect the
2669 * the goal flags (goal_flags)- not
2670 * the current state flags. Then we mark
2671 * things so that the next operation to
2672 * this HBA will cause the update to occur.
2674 if (cts->valid & CCB_TRANS_DISC_VALID) {
2675 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
2676 *dptr |= DPARM_DISC;
2678 *dptr &= ~DPARM_DISC;
2681 if (cts->valid & CCB_TRANS_TQ_VALID) {
2682 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
2683 *dptr |= DPARM_TQING;
2685 *dptr &= ~DPARM_TQING;
2688 if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) {
2689 switch (cts->bus_width) {
2690 case MSG_EXT_WDTR_BUS_16_BIT:
2691 *dptr |= DPARM_WIDE;
2694 *dptr &= ~DPARM_WIDE;
2698 * Any SYNC RATE of nonzero and SYNC_OFFSET
2699 * of nonzero will cause us to go to the
2700 * selected (from NVRAM) maximum value for
2701 * this device. At a later point, we'll
2702 * allow finer control.
2704 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) &&
2705 (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) &&
2706 (cts->sync_offset > 0)) {
2707 *dptr |= DPARM_SYNC;
2709 *dptr &= ~DPARM_SYNC;
2711 *dptr |= DPARM_SAFE_DFLT;
2713 struct ccb_trans_settings_scsi *scsi =
2714 &cts->proto_specific.scsi;
2715 struct ccb_trans_settings_spi *spi =
2716 &cts->xport_specific.spi;
2717 sdparam *sdp = isp->isp_param;
2720 if (spi->valid == 0 && scsi->valid == 0) {
2721 ccb->ccb_h.status = CAM_REQ_CMP;
2726 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2729 * We always update (internally) from goal_flags
2730 * so any request to change settings just gets
2731 * vectored to that location.
2733 dptr = &sdp->isp_devparam[tgt].goal_flags;
2735 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
2736 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
2737 *dptr |= DPARM_DISC;
2739 *dptr &= ~DPARM_DISC;
2742 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
2743 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
2744 *dptr |= DPARM_TQING;
2746 *dptr &= ~DPARM_TQING;
2749 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
2750 if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
2751 *dptr |= DPARM_WIDE;
2753 *dptr &= ~DPARM_WIDE;
2759 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) &&
2760 (spi->valid & CTS_SPI_VALID_SYNC_RATE) &&
2761 (spi->sync_period && spi->sync_offset)) {
2762 *dptr |= DPARM_SYNC;
2764 * XXX: CHECK FOR LEGALITY
2766 sdp->isp_devparam[tgt].goal_period =
2768 sdp->isp_devparam[tgt].goal_offset =
2771 *dptr &= ~DPARM_SYNC;
2774 isp_prt(isp, ISP_LOGDEBUG0,
2775 "SET (%d.%d.%d) to flags %x off %x per %x",
2776 bus, tgt, cts->ccb_h.target_lun,
2777 sdp->isp_devparam[tgt].goal_flags,
2778 sdp->isp_devparam[tgt].goal_offset,
2779 sdp->isp_devparam[tgt].goal_period);
2780 sdp->isp_devparam[tgt].dev_update = 1;
2781 isp->isp_update |= (1 << bus);
2783 ccb->ccb_h.status = CAM_REQ_CMP;
2786 case XPT_GET_TRAN_SETTINGS:
2788 tgt = cts->ccb_h.target_id;
2790 #ifndef CAM_NEW_TRAN_CODE
2792 * a lot of normal SCSI things don't make sense.
2794 cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
2795 cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2797 * How do you measure the width of a high
2798 * speed serial bus? Well, in bytes.
2800 * Offset and period make no sense, though, so we set
2801 * (above) a 'base' transfer speed to be gigabit.
2803 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2805 fcparam *fcp = isp->isp_param;
2806 struct ccb_trans_settings_scsi *scsi =
2807 &cts->proto_specific.scsi;
2808 struct ccb_trans_settings_fc *fc =
2809 &cts->xport_specific.fc;
2811 cts->protocol = PROTO_SCSI;
2812 cts->protocol_version = SCSI_REV_2;
2813 cts->transport = XPORT_FC;
2814 cts->transport_version = 0;
2816 scsi->valid = CTS_SCSI_VALID_TQ;
2817 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
2818 fc->valid = CTS_FC_VALID_SPEED;
2819 fc->bitrate = 100000;
2820 if (fcp->isp_gbspeed == 4 || fcp->isp_gbspeed == 2)
2821 fc->bitrate *= fcp->isp_gbspeed;
2822 if (tgt > 0 && tgt < MAX_FC_TARG) {
2823 fcportdb_t *lp = &fcp->portdb[tgt];
2824 fc->wwnn = lp->node_wwn;
2825 fc->wwpn = lp->port_wwn;
2826 fc->port = lp->portid;
2827 fc->valid |= CTS_FC_VALID_WWNN |
2828 CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT;
2832 #ifdef CAM_NEW_TRAN_CODE
2833 struct ccb_trans_settings_scsi *scsi =
2834 &cts->proto_specific.scsi;
2835 struct ccb_trans_settings_spi *spi =
2836 &cts->xport_specific.spi;
2838 sdparam *sdp = isp->isp_param;
2839 int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2840 uint16_t dval, pval, oval;
2844 if (IS_CURRENT_SETTINGS(cts)) {
2845 sdp->isp_devparam[tgt].dev_refresh = 1;
2846 isp->isp_update |= (1 << bus);
2847 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS,
2849 dval = sdp->isp_devparam[tgt].actv_flags;
2850 oval = sdp->isp_devparam[tgt].actv_offset;
2851 pval = sdp->isp_devparam[tgt].actv_period;
2853 dval = sdp->isp_devparam[tgt].nvrm_flags;
2854 oval = sdp->isp_devparam[tgt].nvrm_offset;
2855 pval = sdp->isp_devparam[tgt].nvrm_period;
2858 #ifndef CAM_NEW_TRAN_CODE
2859 cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
2861 if (dval & DPARM_DISC) {
2862 cts->flags |= CCB_TRANS_DISC_ENB;
2864 if (dval & DPARM_TQING) {
2865 cts->flags |= CCB_TRANS_TAG_ENB;
2867 if (dval & DPARM_WIDE) {
2868 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2870 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2872 cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
2873 CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2875 if ((dval & DPARM_SYNC) && oval != 0) {
2876 cts->sync_period = pval;
2877 cts->sync_offset = oval;
2879 CCB_TRANS_SYNC_RATE_VALID |
2880 CCB_TRANS_SYNC_OFFSET_VALID;
2883 cts->protocol = PROTO_SCSI;
2884 cts->protocol_version = SCSI_REV_2;
2885 cts->transport = XPORT_SPI;
2886 cts->transport_version = 2;
2892 if (dval & DPARM_DISC) {
2893 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
2895 if ((dval & DPARM_SYNC) && oval && pval) {
2896 spi->sync_offset = oval;
2897 spi->sync_period = pval;
2899 spi->sync_offset = 0;
2900 spi->sync_period = 0;
2902 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
2903 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
2904 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
2905 if (dval & DPARM_WIDE) {
2906 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2908 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2910 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
2911 scsi->valid = CTS_SCSI_VALID_TQ;
2912 if (dval & DPARM_TQING) {
2913 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
2915 spi->valid |= CTS_SPI_VALID_DISC;
2918 isp_prt(isp, ISP_LOGDEBUG0,
2919 "GET %s (%d.%d.%d) to flags %x off %x per %x",
2920 IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
2921 bus, tgt, cts->ccb_h.target_lun, dval, oval, pval);
2923 ccb->ccb_h.status = CAM_REQ_CMP;
2927 case XPT_CALC_GEOMETRY:
2928 #if __FreeBSD_version < 500000
2930 struct ccb_calc_geometry *ccg;
2931 u_int32_t secs_per_cylinder;
2935 if (ccg->block_size == 0) {
2936 ccb->ccb_h.status = CAM_REQ_INVALID;
2940 size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size);
2941 if (size_mb > 1024) {
2943 ccg->secs_per_track = 63;
2946 ccg->secs_per_track = 32;
2948 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2949 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2950 ccb->ccb_h.status = CAM_REQ_CMP;
2956 cam_calc_geometry(&ccb->ccg, /*extended*/1);
2961 case XPT_RESET_BUS: /* Reset the specified bus */
2962 bus = cam_sim_bus(sim);
2963 error = isp_control(isp, ISPCTL_RESET_BUS, &bus);
2965 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2968 xpt_print(ccb->ccb_h.path, "reset bus\n");
2970 if (cam_sim_bus(sim) && isp->isp_path2 != NULL)
2971 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
2972 else if (isp->isp_path != NULL)
2973 xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
2974 ccb->ccb_h.status = CAM_REQ_CMP;
2979 case XPT_TERM_IO: /* Terminate the I/O process */
2980 ccb->ccb_h.status = CAM_REQ_INVALID;
2984 case XPT_PATH_INQ: /* Path routing inquiry */
2986 struct ccb_pathinq *cpi = &ccb->cpi;
2988 cpi->version_num = 1;
2989 #ifdef ISP_TARGET_MODE
2990 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
2992 cpi->target_sprt = 0;
2994 cpi->hba_eng_cnt = 0;
2995 cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
2996 cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
2997 cpi->bus_id = cam_sim_bus(sim);
2999 cpi->hba_misc = PIM_NOBUSRESET;
3001 * Because our loop ID can shift from time to time,
3002 * make our initiator ID out of range of our bus.
3004 cpi->initiator_id = cpi->max_target + 1;
3007 * Set base transfer capabilities for Fibre Channel.
3008 * Technically not correct because we don't know
3009 * what media we're running on top of- but we'll
3010 * look good if we always say 100MB/s.
3012 cpi->base_transfer_speed = 100000;
3013 if (FCPARAM(isp)->isp_gbspeed == 4 ||
3014 FCPARAM(isp)->isp_gbspeed == 2)
3015 cpi->base_transfer_speed *=
3016 FCPARAM(isp)->isp_gbspeed;
3017 cpi->hba_inquiry = PI_TAG_ABLE;
3018 #ifdef CAM_NEW_TRAN_CODE
3019 cpi->transport = XPORT_FC;
3020 cpi->transport_version = 0;
3023 sdparam *sdp = isp->isp_param;
3024 sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
3025 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
3027 cpi->initiator_id = sdp->isp_initiator_id;
3028 cpi->base_transfer_speed = 3300;
3029 #ifdef CAM_NEW_TRAN_CODE
3030 cpi->transport = XPORT_SPI;
3031 cpi->transport_version = 2;
3034 #ifdef CAM_NEW_TRAN_CODE
3035 cpi->protocol = PROTO_SCSI;
3036 cpi->protocol_version = SCSI_REV_2;
3038 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
3039 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
3040 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
3041 cpi->unit_number = cam_sim_unit(sim);
3042 cpi->ccb_h.status = CAM_REQ_CMP;
3047 ccb->ccb_h.status = CAM_REQ_INVALID;
3053 #define ISPDDB (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
3056 isp_done(struct ccb_scsiio *sccb)
3058 ispsoftc_t *isp = XS_ISP(sccb);
3061 XS_SETERR(sccb, CAM_REQ_CMP);
3063 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
3064 (sccb->scsi_status != SCSI_STATUS_OK)) {
3065 sccb->ccb_h.status &= ~CAM_STATUS_MASK;
3066 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) &&
3067 (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
3068 sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
3070 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
3074 sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3075 if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3076 isp_prt(isp, ISP_LOGDEBUG0,
3077 "target %d lun %d CAM status 0x%x SCSI status 0x%x",
3078 XS_TGT(sccb), XS_LUN(sccb), sccb->ccb_h.status,
3080 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
3081 sccb->ccb_h.status |= CAM_DEV_QFRZN;
3082 xpt_freeze_devq(sccb->ccb_h.path, 1);
3086 if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) &&
3087 (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3088 xpt_print(sccb->ccb_h.path,
3089 "cam completion status 0x%x\n", sccb->ccb_h.status);
3092 XS_CMD_S_DONE(sccb);
3093 if (XS_CMD_WDOG_P(sccb) == 0) {
3094 untimeout(isp_watchdog, sccb, sccb->ccb_h.timeout_ch);
3095 if (XS_CMD_GRACE_P(sccb)) {
3096 isp_prt(isp, ISP_LOGDEBUG2,
3097 "finished command on borrowed time");
3099 XS_CMD_S_CLEAR(sccb);
3100 isp_free_pcmd(isp, (union ccb *) sccb);
3101 xpt_done((union ccb *) sccb);
3106 isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg)
3109 static const char prom[] =
3110 "PortID 0x%06x handle 0x%x role %s %s\n"
3111 " WWNN 0x%08x%08x WWPN 0x%08x%08x";
3112 static const char prom2[] =
3113 "PortID 0x%06x handle 0x%x role %s %s tgt %u\n"
3114 " WWNN 0x%08x%08x WWPN 0x%08x%08x";
3118 struct cam_path *tmppath;
3121 case ISPASYNC_NEW_TGT_PARAMS:
3123 #ifdef CAM_NEW_TRAN_CODE
3124 struct ccb_trans_settings_scsi *scsi;
3125 struct ccb_trans_settings_spi *spi;
3128 sdparam *sdp = isp->isp_param;
3129 struct ccb_trans_settings cts;
3131 memset(&cts, 0, sizeof (struct ccb_trans_settings));
3133 tgt = *((int *)arg);
3134 bus = (tgt >> 16) & 0xffff;
3137 if (xpt_create_path(&tmppath, NULL,
3138 cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim),
3139 tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
3140 isp_prt(isp, ISP_LOGWARN,
3141 "isp_async cannot make temp path for %d.%d",
3146 flags = sdp->isp_devparam[tgt].actv_flags;
3147 #ifdef CAM_NEW_TRAN_CODE
3148 cts.type = CTS_TYPE_CURRENT_SETTINGS;
3149 cts.protocol = PROTO_SCSI;
3150 cts.transport = XPORT_SPI;
3152 scsi = &cts.proto_specific.scsi;
3153 spi = &cts.xport_specific.spi;
3155 if (flags & DPARM_TQING) {
3156 scsi->valid |= CTS_SCSI_VALID_TQ;
3157 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3160 if (flags & DPARM_DISC) {
3161 spi->valid |= CTS_SPI_VALID_DISC;
3162 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3164 spi->flags |= CTS_SPI_VALID_BUS_WIDTH;
3165 if (flags & DPARM_WIDE) {
3166 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
3168 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
3170 if (flags & DPARM_SYNC) {
3171 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3172 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3173 spi->sync_period = sdp->isp_devparam[tgt].actv_period;
3174 spi->sync_offset = sdp->isp_devparam[tgt].actv_offset;
3177 cts.flags = CCB_TRANS_CURRENT_SETTINGS;
3178 cts.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
3179 if (flags & DPARM_DISC) {
3180 cts.flags |= CCB_TRANS_DISC_ENB;
3182 if (flags & DPARM_TQING) {
3183 cts.flags |= CCB_TRANS_TAG_ENB;
3185 cts.valid |= CCB_TRANS_BUS_WIDTH_VALID;
3186 cts.bus_width = (flags & DPARM_WIDE)?
3187 MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT;
3188 cts.sync_period = sdp->isp_devparam[tgt].actv_period;
3189 cts.sync_offset = sdp->isp_devparam[tgt].actv_offset;
3190 if (flags & DPARM_SYNC) {
3192 CCB_TRANS_SYNC_RATE_VALID |
3193 CCB_TRANS_SYNC_OFFSET_VALID;
3196 isp_prt(isp, ISP_LOGDEBUG2,
3197 "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x",
3198 bus, tgt, sdp->isp_devparam[tgt].actv_period,
3199 sdp->isp_devparam[tgt].actv_offset, flags);
3200 xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
3201 xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
3202 xpt_free_path(tmppath);
3205 case ISPASYNC_BUS_RESET:
3206 bus = *((int *)arg);
3207 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected",
3209 if (bus > 0 && isp->isp_path2) {
3210 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
3211 } else if (isp->isp_path) {
3212 xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
3217 msg = "LIP Received";
3220 case ISPASYNC_LOOP_RESET:
3225 case ISPASYNC_LOOP_DOWN:
3229 if (isp->isp_path) {
3230 isp_freeze_loopdown(isp, msg);
3232 if (isp->isp_osinfo.ldt_running == 0) {
3233 isp->isp_osinfo.ldt_running = 1;
3234 callout_reset(&isp->isp_osinfo.ldt,
3235 isp->isp_osinfo.loop_down_limit * hz, isp_ldt, isp);
3236 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3237 "starting Loop Down Timer");
3239 isp_prt(isp, ISP_LOGINFO, msg);
3241 case ISPASYNC_LOOP_UP:
3243 * Now we just note that Loop has come up. We don't
3244 * actually do anything because we're waiting for a
3245 * Change Notify before activating the FC cleanup
3246 * thread to look at the state of the loop again.
3248 isp_prt(isp, ISP_LOGINFO, "Loop UP");
3250 case ISPASYNC_DEV_ARRIVED:
3253 if ((isp->isp_role & ISP_ROLE_INITIATOR) &&
3254 (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
3255 int dbidx = lp - FCPARAM(isp)->portdb;
3258 for (i = 0; i < MAX_FC_TARG; i++) {
3259 if (i >= FL_ID && i <= SNS_ID) {
3262 if (FCPARAM(isp)->isp_ini_map[i] == 0) {
3266 if (i < MAX_FC_TARG) {
3267 FCPARAM(isp)->isp_ini_map[i] = dbidx + 1;
3268 lp->ini_map_idx = i + 1;
3270 isp_prt(isp, ISP_LOGWARN, "out of target ids");
3271 isp_dump_portdb(isp);
3274 if (lp->ini_map_idx) {
3275 tgt = lp->ini_map_idx - 1;
3276 isp_prt(isp, ISP_LOGCONFIG, prom2,
3277 lp->portid, lp->handle,
3278 roles[lp->roles], "arrived at", tgt,
3279 (uint32_t) (lp->node_wwn >> 32),
3280 (uint32_t) lp->node_wwn,
3281 (uint32_t) (lp->port_wwn >> 32),
3282 (uint32_t) lp->port_wwn);
3283 isp_make_here(isp, tgt);
3285 isp_prt(isp, ISP_LOGCONFIG, prom,
3286 lp->portid, lp->handle,
3287 roles[lp->roles], "arrived",
3288 (uint32_t) (lp->node_wwn >> 32),
3289 (uint32_t) lp->node_wwn,
3290 (uint32_t) (lp->port_wwn >> 32),
3291 (uint32_t) lp->port_wwn);
3294 case ISPASYNC_DEV_CHANGED:
3296 if (isp_change_is_bad) {
3297 lp->state = FC_PORTDB_STATE_NIL;
3298 if (lp->ini_map_idx) {
3299 tgt = lp->ini_map_idx - 1;
3300 FCPARAM(isp)->isp_ini_map[tgt] = 0;
3301 lp->ini_map_idx = 0;
3302 isp_prt(isp, ISP_LOGCONFIG, prom3,
3303 lp->portid, tgt, "change is bad");
3304 isp_make_gone(isp, tgt);
3306 isp_prt(isp, ISP_LOGCONFIG, prom,
3307 lp->portid, lp->handle,
3309 "changed and departed",
3310 (uint32_t) (lp->node_wwn >> 32),
3311 (uint32_t) lp->node_wwn,
3312 (uint32_t) (lp->port_wwn >> 32),
3313 (uint32_t) lp->port_wwn);
3316 lp->portid = lp->new_portid;
3317 lp->roles = lp->new_roles;
3318 if (lp->ini_map_idx) {
3319 int t = lp->ini_map_idx - 1;
3320 FCPARAM(isp)->isp_ini_map[t] =
3321 (lp - FCPARAM(isp)->portdb) + 1;
3322 tgt = lp->ini_map_idx - 1;
3323 isp_prt(isp, ISP_LOGCONFIG, prom2,
3324 lp->portid, lp->handle,
3325 roles[lp->roles], "changed at", tgt,
3326 (uint32_t) (lp->node_wwn >> 32),
3327 (uint32_t) lp->node_wwn,
3328 (uint32_t) (lp->port_wwn >> 32),
3329 (uint32_t) lp->port_wwn);
3331 isp_prt(isp, ISP_LOGCONFIG, prom,
3332 lp->portid, lp->handle,
3333 roles[lp->roles], "changed",
3334 (uint32_t) (lp->node_wwn >> 32),
3335 (uint32_t) lp->node_wwn,
3336 (uint32_t) (lp->port_wwn >> 32),
3337 (uint32_t) lp->port_wwn);
3341 case ISPASYNC_DEV_STAYED:
3343 if (lp->ini_map_idx) {
3344 tgt = lp->ini_map_idx - 1;
3345 isp_prt(isp, ISP_LOGCONFIG, prom2,
3346 lp->portid, lp->handle,
3347 roles[lp->roles], "stayed at", tgt,
3348 (uint32_t) (lp->node_wwn >> 32),
3349 (uint32_t) lp->node_wwn,
3350 (uint32_t) (lp->port_wwn >> 32),
3351 (uint32_t) lp->port_wwn);
3353 isp_prt(isp, ISP_LOGCONFIG, prom,
3354 lp->portid, lp->handle,
3355 roles[lp->roles], "stayed",
3356 (uint32_t) (lp->node_wwn >> 32),
3357 (uint32_t) lp->node_wwn,
3358 (uint32_t) (lp->port_wwn >> 32),
3359 (uint32_t) lp->port_wwn);
3362 case ISPASYNC_DEV_GONE:
3365 * If this has a virtual target and we haven't marked it
3366 * that we're going to have isp_gdt tell the OS it's gone,
3367 * set the isp_gdt timer running on it.
3369 * If it isn't marked that isp_gdt is going to get rid of it,
3370 * announce that it's gone.
3372 if (lp->ini_map_idx && lp->reserved == 0) {
3374 lp->new_reserved = isp->isp_osinfo.gone_device_time;
3375 lp->state = FC_PORTDB_STATE_ZOMBIE;
3376 if (isp->isp_osinfo.gdt_running == 0) {
3377 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3378 "starting Gone Device Timer");
3379 isp->isp_osinfo.gdt_running = 1;
3380 callout_reset(&isp->isp_osinfo.gdt, hz,
3383 tgt = lp->ini_map_idx - 1;
3384 isp_prt(isp, ISP_LOGCONFIG, prom2,
3385 lp->portid, lp->handle,
3386 roles[lp->roles], "gone zombie at", tgt,
3387 (uint32_t) (lp->node_wwn >> 32),
3388 (uint32_t) lp->node_wwn,
3389 (uint32_t) (lp->port_wwn >> 32),
3390 (uint32_t) lp->port_wwn);
3391 } else if (lp->reserved == 0) {
3392 isp_prt(isp, ISP_LOGCONFIG, prom,
3393 lp->portid, lp->handle,
3394 roles[lp->roles], "departed",
3395 (uint32_t) (lp->node_wwn >> 32),
3396 (uint32_t) lp->node_wwn,
3397 (uint32_t) (lp->port_wwn >> 32),
3398 (uint32_t) lp->port_wwn);
3401 case ISPASYNC_CHANGE_NOTIFY:
3404 if (arg == ISPASYNC_CHANGE_PDB) {
3405 msg = "Port Database Changed";
3406 } else if (arg == ISPASYNC_CHANGE_SNS) {
3407 msg = "Name Server Database Changed";
3409 msg = "Other Change Notify";
3412 * If the loop down timer is running, cancel it.
3414 if (isp->isp_osinfo.ldt_running) {
3415 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3416 "Stopping Loop Down Timer");
3417 isp->isp_osinfo.ldt_running = 0;
3418 callout_stop(&isp->isp_osinfo.ldt);
3420 isp_prt(isp, ISP_LOGINFO, msg);
3421 isp_freeze_loopdown(isp, msg);
3422 wakeup(ISP_KT_WCHAN(isp));
3425 #ifdef ISP_TARGET_MODE
3426 case ISPASYNC_TARGET_NOTIFY:
3428 tmd_notify_t *nt = arg;
3429 isp_prt(isp, ISP_LOGALL,
3430 "target notify code 0x%x", nt->nt_ncode);
3433 case ISPASYNC_TARGET_ACTION:
3434 switch (((isphdr_t *)arg)->rqs_entry_type) {
3436 isp_prt(isp, ISP_LOGWARN,
3437 "event 0x%x for unhandled target action",
3438 ((isphdr_t *)arg)->rqs_entry_type);
3440 case RQSTYPE_NOTIFY:
3442 rv = isp_handle_platform_notify_scsi(isp,
3443 (in_entry_t *) arg);
3445 rv = isp_handle_platform_notify_fc(isp,
3446 (in_fcentry_t *) arg);
3450 rv = isp_handle_platform_atio(isp, (at_entry_t *) arg);
3453 rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg);
3458 rv = isp_handle_platform_ctio(isp, arg);
3460 case RQSTYPE_ENABLE_LUN:
3461 case RQSTYPE_MODIFY_LUN:
3462 isp_ledone(isp, (lun_entry_t *) arg);
3467 case ISPASYNC_FW_CRASH:
3469 uint16_t mbox1, mbox6;
3470 mbox1 = ISP_READ(isp, OUTMAILBOX1);
3471 if (IS_DUALBUS(isp)) {
3472 mbox6 = ISP_READ(isp, OUTMAILBOX6);
3476 isp_prt(isp, ISP_LOGERR,
3477 "Internal Firmware Error on bus %d @ RISC Address 0x%x",
3479 #ifdef ISP_FW_CRASH_DUMP
3480 mbox1 = isp->isp_osinfo.mbox_sleep_ok;
3481 isp->isp_osinfo.mbox_sleep_ok = 0;
3483 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
3484 FCPARAM(isp)->isp_loopstate = LOOP_NIL;
3485 isp_freeze_loopdown(isp, "f/w crash");
3489 isp->isp_osinfo.mbox_sleep_ok = mbox1;
3491 mbox1 = isp->isp_osinfo.mbox_sleep_ok;
3492 isp->isp_osinfo.mbox_sleep_ok = 0;
3494 isp->isp_osinfo.mbox_sleep_ok = mbox1;
3496 isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
3499 case ISPASYNC_UNHANDLED_RESPONSE:
3502 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
3510 * Locks are held before coming here.
3513 isp_uninit(ispsoftc_t *isp)
3516 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
3518 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
3520 ISP_DISABLE_INTS(isp);
3524 isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
3527 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
3530 printf("%s: ", device_get_nameunit(isp->isp_dev));
3538 isp_nanotime_sub(struct timespec *b, struct timespec *a)
3541 struct timespec x = *b;
3543 elapsed = GET_NANOSEC(&x);
3550 isp_mbox_acquire(ispsoftc_t *isp)
3552 if (isp->isp_osinfo.mboxbsy) {
3555 isp->isp_osinfo.mboxcmd_done = 0;
3556 isp->isp_osinfo.mboxbsy = 1;
3562 isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
3564 unsigned int usecs = mbp->timeout;
3565 unsigned int max, olim, ilim;
3568 usecs = MBCMD_DEFAULT_TIMEOUT;
3570 max = isp->isp_mbxwrk0 + 1;
3572 if (isp->isp_osinfo.mbox_sleep_ok) {
3573 unsigned int ms = (usecs + 999) / 1000;
3575 isp->isp_osinfo.mbox_sleep_ok = 0;
3576 isp->isp_osinfo.mbox_sleeping = 1;
3577 for (olim = 0; olim < max; olim++) {
3578 #if __FreeBSD_version < 700037
3579 tsleep(&isp->isp_mbxworkp, PRIBIO, "ispmbx_sleep",
3582 msleep(&isp->isp_mbxworkp, &isp->isp_osinfo.lock,
3583 PRIBIO, "ispmbx_sleep", isp_mstohz(ms));
3585 if (isp->isp_osinfo.mboxcmd_done) {
3589 isp->isp_osinfo.mbox_sleep_ok = 1;
3590 isp->isp_osinfo.mbox_sleeping = 0;
3592 for (olim = 0; olim < max; olim++) {
3593 for (ilim = 0; ilim < usecs; ilim += 100) {
3595 uint16_t sema, mbox;
3596 if (isp->isp_osinfo.mboxcmd_done) {
3599 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
3600 isp_intr(isp, isr, sema, mbox);
3601 if (isp->isp_osinfo.mboxcmd_done) {
3607 if (isp->isp_osinfo.mboxcmd_done) {
3612 if (isp->isp_osinfo.mboxcmd_done == 0) {
3613 isp_prt(isp, ISP_LOGWARN,
3614 "%s Mailbox Command (0x%x) Timeout (%uus)",
3615 isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled",
3616 isp->isp_lastmbxcmd, usecs);
3617 mbp->param[0] = MBOX_TIMEOUT;
3618 isp->isp_osinfo.mboxcmd_done = 1;
3623 isp_mbox_notify_done(ispsoftc_t *isp)
3625 if (isp->isp_osinfo.mbox_sleeping) {
3626 wakeup(&isp->isp_mbxworkp);
3628 isp->isp_osinfo.mboxcmd_done = 1;
3632 isp_mbox_release(ispsoftc_t *isp)
3634 isp->isp_osinfo.mboxbsy = 0;
3642 t.tv_sec = ms / 1000;
3643 t.tv_usec = (ms % 1000) * 1000;
3655 isp_platform_intr(void *arg)
3657 ispsoftc_t *isp = arg;
3659 uint16_t sema, mbox;
3663 if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
3664 isp->isp_intbogus++;
3666 isp_intr(isp, isr, sema, mbox);
3672 isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl)
3674 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
3675 bus_dmamap_sync(isp->isp_osinfo.dmat,
3676 PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTREAD);
3678 bus_dmamap_sync(isp->isp_osinfo.dmat,
3679 PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTWRITE);
3681 bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap);