Deleted Added
full compact
isp_freebsd.c (191979) isp_freebsd.c (196008)
1/*-
1/*-
2 * Copyright (c) 1997-2006 by Matthew Jacob
2 * Copyright (c) 1997-2009 by Matthew Jacob
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice immediately at the beginning of the file, without modification,
10 * this list of conditions, and the following disclaimer.

--- 12 unchanged lines hidden (view full) ---

23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
29 */
30#include <sys/cdefs.h>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice immediately at the beginning of the file, without modification,
10 * this list of conditions, and the following disclaimer.

--- 12 unchanged lines hidden (view full) ---

23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
29 */
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/isp/isp_freebsd.c 191979 2009-05-10 20:14:19Z marius $");
31__FBSDID("$FreeBSD: head/sys/dev/isp/isp_freebsd.c 196008 2009-08-01 01:04:26Z mjacob $");
32#include <dev/isp/isp_freebsd.h>
33#include <sys/unistd.h>
34#include <sys/kthread.h>
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>
35#include <sys/conf.h>
36#include <sys/module.h>
37#include <sys/ioccom.h>
38#include <dev/isp/isp_ioctl.h>
40#if __FreeBSD_version >= 500000
41#include <sys/sysctl.h>
42#else
43#include <sys/devicestat.h>
39#include <sys/devicestat.h>
44#endif
45#include <cam/cam_periph.h>
46#include <cam/cam_xpt_periph.h>
47
40#include <cam/cam_periph.h>
41#include <cam/cam_xpt_periph.h>
42
48#if !defined(CAM_NEW_TRAN_CODE) && __FreeBSD_version >= 700025
49#define CAM_NEW_TRAN_CODE 1
43#if __FreeBSD_version < 800002
44#define THREAD_CREATE kthread_create
45#else
46#define THREAD_CREATE kproc_create
50#endif
51
47#endif
48
52
53MODULE_VERSION(isp, 1);
54MODULE_DEPEND(isp, cam, 1, 1, 1);
55int isp_announced = 0;
49MODULE_VERSION(isp, 1);
50MODULE_DEPEND(isp, cam, 1, 1, 1);
51int isp_announced = 0;
56int isp_fabric_hysteresis = 5;
57int isp_loop_down_limit = 300; /* default loop down limit */
52int isp_fabric_hysteresis = 3;
53int isp_loop_down_limit = 60; /* default loop down limit */
58int isp_change_is_bad = 0; /* "changed" devices are bad */
54int isp_change_is_bad = 0; /* "changed" devices are bad */
59int isp_quickboot_time = 15; /* don't wait more than N secs for loop up */
55int isp_quickboot_time = 7; /* don't wait more than N secs for loop up */
60int isp_gone_device_time = 30; /* grace time before reporting device lost */
56int isp_gone_device_time = 30; /* grace time before reporting device lost */
57int isp_autoconfig = 1; /* automatically attach/detach devices */
61static const char *roles[4] = {
62 "(none)", "Target", "Initiator", "Target/Initiator"
63};
58static const char *roles[4] = {
59 "(none)", "Target", "Initiator", "Target/Initiator"
60};
64static const char prom3[] =
65 "PortID 0x%06x Departed from Target %u because of %s";
61static const char prom3[] = "Chan %d PortID 0x%06x Departed from Target %u because of %s";
62static const char rqo[] = "%s: Request Queue Overflow\n";
66
63
67static void isp_freeze_loopdown(ispsoftc_t *, char *);
64static void isp_freeze_loopdown(ispsoftc_t *, int, char *);
68static d_ioctl_t ispioctl;
69static void isp_intr_enable(void *);
70static void isp_cam_async(void *, uint32_t, struct cam_path *, void *);
71static void isp_poll(struct cam_sim *);
72static timeout_t isp_watchdog;
73static timeout_t isp_ldt;
74static void isp_kthread(void *);
75static void isp_action(struct cam_sim *, union ccb *);
65static d_ioctl_t ispioctl;
66static void isp_intr_enable(void *);
67static void isp_cam_async(void *, uint32_t, struct cam_path *, void *);
68static void isp_poll(struct cam_sim *);
69static timeout_t isp_watchdog;
70static timeout_t isp_ldt;
71static void isp_kthread(void *);
72static void isp_action(struct cam_sim *, union ccb *);
76
77#if __FreeBSD_version < 700000
78ispfwfunc *isp_get_firmware_p = NULL;
73#ifdef ISP_INTERNAL_TARGET
74static void isp_target_thread_pi(void *);
75static void isp_target_thread_fc(void *);
79#endif
76#endif
77static void isp_timer(void *);
80
78
81#if __FreeBSD_version < 500000
82#define ISP_CDEV_MAJOR 248
83static struct cdevsw isp_cdevsw = {
79static struct cdevsw isp_cdevsw = {
84 /* open */ nullopen,
85 /* close */ nullclose,
86 /* read */ noread,
87 /* write */ nowrite,
88 /* ioctl */ ispioctl,
89 /* poll */ nopoll,
90 /* mmap */ nommap,
91 /* strategy */ nostrategy,
92 /* name */ "isp",
93 /* maj */ ISP_CDEV_MAJOR,
94 /* dump */ nodump,
95 /* psize */ nopsize,
96 /* flags */ D_TAPE,
97};
98#define isp_sysctl_update(x) do { ; } while (0)
99#else
100static struct cdevsw isp_cdevsw = {
101 .d_version = D_VERSION,
80 .d_version = D_VERSION,
102#if __FreeBSD_version < 700037
103 .d_flags = D_NEEDGIANT,
104#endif
105 .d_ioctl = ispioctl,
106 .d_name = "isp",
107};
81 .d_ioctl = ispioctl,
82 .d_name = "isp",
83};
108static void isp_sysctl_update(ispsoftc_t *);
109#endif
110
84
111static ispsoftc_t *isplist = NULL;
112
113void
114isp_attach(ispsoftc_t *isp)
85static int
86isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
115{
87{
116 int primary, secondary;
117 struct ccb_setasync csa;
88 struct ccb_setasync csa;
118 struct cam_devq *devq;
119 struct cam_sim *sim;
120 struct cam_path *path;
121
122 /*
89 struct cam_sim *sim;
90 struct cam_path *path;
91
92 /*
123 * Establish (in case of 12X0) which bus is the primary.
124 */
125
126 primary = 0;
127 secondary = 1;
128
129 /*
130 * Create the device queue for our SIM(s).
131 */
132 devq = cam_simq_alloc(isp->isp_maxcmds);
133 if (devq == NULL) {
134 return;
135 }
136
137 /*
138 * Construct our SIM entry.
139 */
93 * Construct our SIM entry.
94 */
140 sim = isp_sim_alloc(isp_action, isp_poll, "isp", isp,
141 device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
95 sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp, device_get_unit(isp->isp_dev), &isp->isp_osinfo.lock, isp->isp_maxcmds, isp->isp_maxcmds, devq);
96
142 if (sim == NULL) {
97 if (sim == NULL) {
143 cam_simq_free(devq);
144 return;
98 return (ENOMEM);
145 }
146
99 }
100
147 isp->isp_osinfo.ehook.ich_func = isp_intr_enable;
148 isp->isp_osinfo.ehook.ich_arg = isp;
149 ISP_UNLOCK(isp);
150 if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) {
151 ISP_LOCK(isp);
152 cam_sim_free(sim, TRUE);
153 isp_prt(isp, ISP_LOGERR,
154 "could not establish interrupt enable hook");
155 return;
156 }
157 ISP_LOCK(isp);
101 ISP_LOCK(isp);
158
159 if (xpt_bus_register(sim, isp->isp_dev, primary) != CAM_SUCCESS) {
160 cam_sim_free(sim, TRUE);
161 return;
102 if (xpt_bus_register(sim, isp->isp_dev, chan) != CAM_SUCCESS) {
103 ISP_UNLOCK(isp);
104 cam_sim_free(sim, FALSE);
105 return (EIO);
162 }
106 }
107 ISP_UNLOCK(isp);
163
108
164 if (xpt_create_path(&path, NULL, cam_sim_path(sim),
165 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
109 if (xpt_create_path(&path, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
110 ISP_LOCK(isp);
166 xpt_bus_deregister(cam_sim_path(sim));
111 xpt_bus_deregister(cam_sim_path(sim));
167 cam_sim_free(sim, TRUE);
168 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
169 return;
112 ISP_UNLOCK(isp);
113 cam_sim_free(sim, FALSE);
114 return (ENXIO);
170 }
171
172 xpt_setup_ccb(&csa.ccb_h, path, 5);
173 csa.ccb_h.func_code = XPT_SASYNC_CB;
174 csa.event_enable = AC_LOST_DEVICE;
175 csa.callback = isp_cam_async;
176 csa.callback_arg = sim;
177 xpt_action((union ccb *)&csa);
115 }
116
117 xpt_setup_ccb(&csa.ccb_h, path, 5);
118 csa.ccb_h.func_code = XPT_SASYNC_CB;
119 csa.event_enable = AC_LOST_DEVICE;
120 csa.callback = isp_cam_async;
121 csa.callback_arg = sim;
122 xpt_action((union ccb *)&csa);
178 isp->isp_sim = sim;
179 isp->isp_path = path;
180
123
181 /*
182 * If we have a second channel, construct SIM entry for that.
183 */
184 if (IS_DUALBUS(isp)) {
185 sim = isp_sim_alloc(isp_action, isp_poll, "isp", isp,
186 device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
187 if (sim == NULL) {
188 xpt_bus_deregister(cam_sim_path(isp->isp_sim));
189 xpt_free_path(isp->isp_path);
190 cam_simq_free(devq);
191 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
192 return;
124 if (IS_SCSI(isp)) {
125 struct isp_spi *spi = ISP_SPI_PC(isp, chan);
126 spi->sim = sim;
127 spi->path = path;
128#ifdef ISP_INTERNAL_TARGET
129 ISP_SET_PC(isp, chan, proc_active, 1);
130 if (THREAD_CREATE(isp_target_thread_pi, spi, &spi->target_proc, 0, 0, "%s: isp_test_tgt%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
131 ISP_SET_PC(isp, chan, proc_active, 0);
132 isp_prt(isp, ISP_LOGERR, "cannot create test target thread");
193 }
133 }
194 if (xpt_bus_register(sim, isp->isp_dev, secondary) !=
195 CAM_SUCCESS) {
196 xpt_bus_deregister(cam_sim_path(isp->isp_sim));
197 xpt_free_path(isp->isp_path);
198 cam_sim_free(sim, TRUE);
199 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
200 return;
201 }
134#endif
135 } else {
136 struct isp_fc *fc = ISP_FC_PC(isp, chan);
202
137
203 if (xpt_create_path(&path, NULL, cam_sim_path(sim),
204 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
205 xpt_bus_deregister(cam_sim_path(isp->isp_sim));
206 xpt_free_path(isp->isp_path);
207 xpt_bus_deregister(cam_sim_path(sim));
208 cam_sim_free(sim, TRUE);
209 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
210 return;
138 fc->sim = sim;
139 fc->path = path;
140 fc->isp = isp;
141
142 callout_init_mtx(&fc->ldt, &isp->isp_osinfo.lock, 0);
143 callout_init_mtx(&fc->gdt, &isp->isp_osinfo.lock, 0);
144
145 if (THREAD_CREATE(isp_kthread, fc, &fc->kproc, 0, 0, "%s: fc_thrd%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
146 xpt_free_path(fc->path);
147 ISP_LOCK(isp);
148 xpt_bus_deregister(cam_sim_path(fc->sim));
149 ISP_UNLOCK(isp);
150 cam_sim_free(fc->sim, FALSE);
211 }
151 }
152 /*
153 * We start by being "loop down" if we have an initiator role
154 */
155 ISP_LOCK(isp);
156 if ((FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR) && fc->ldt_running == 0) {
157 isp_freeze_loopdown(isp, chan, "isp_attach");
158 fc->ldt_running = 1;
159 callout_reset(&fc->ldt, isp_quickboot_time * hz, isp_ldt, fc);
160 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Starting Initial Loop Down Timer @ %lu", (unsigned long) time_uptime);
161 }
162 ISP_UNLOCK(isp);
163#ifdef ISP_INTERNAL_TARGET
164 ISP_SET_PC(isp, chan, proc_active, 1);
165 if (THREAD_CREATE(isp_target_thread_fc, fc, &fc->target_proc, 0, 0, "%s: isp_test_tgt%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
166 ISP_SET_PC(isp, chan, proc_active, 0);
167 isp_prt(isp, ISP_LOGERR, "cannot create test target thread");
168 }
169#endif
170 }
171 return (0);
172}
212
173
213 xpt_setup_ccb(&csa.ccb_h, path, 5);
214 csa.ccb_h.func_code = XPT_SASYNC_CB;
215 csa.event_enable = AC_LOST_DEVICE;
216 csa.callback = isp_cam_async;
217 csa.callback_arg = sim;
218 xpt_action((union ccb *)&csa);
219 isp->isp_sim2 = sim;
220 isp->isp_path2 = path;
174int
175isp_attach(ispsoftc_t *isp)
176{
177 const char *nu = device_get_nameunit(isp->isp_osinfo.dev);
178 int du = device_get_unit(isp->isp_dev);
179 int chan;
180
181 isp->isp_osinfo.ehook.ich_func = isp_intr_enable;
182 isp->isp_osinfo.ehook.ich_arg = isp;
183 if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) {
184 isp_prt(isp, ISP_LOGERR, "could not establish interrupt enable hook");
185 return (-EIO);
221 }
186 }
187 isp->isp_osinfo.ehook_active = 1;
222
188
189
223 /*
190 /*
224 * Create device nodes
191 * Create the device queue for our SIM(s).
225 */
192 */
226 ISP_UNLOCK(isp);
227 (void) make_dev(&isp_cdevsw, device_get_unit(isp->isp_dev), UID_ROOT,
228 GID_OPERATOR, 0600, "%s", device_get_nameunit(isp->isp_dev));
229 isp_sysctl_update(isp);
230 ISP_LOCK(isp);
231
232 if (isp->isp_role != ISP_ROLE_NONE) {
233 isp->isp_state = ISP_RUNSTATE;
234 ISP_ENABLE_INTS(isp);
193 isp->isp_osinfo.devq = cam_simq_alloc(isp->isp_maxcmds);
194 if (isp->isp_osinfo.devq == NULL) {
195 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
196 return (EIO);
235 }
197 }
236 if (isplist == NULL) {
237 isplist = isp;
238 } else {
239 ispsoftc_t *tmp = isplist;
240 while (tmp->isp_osinfo.next) {
241 tmp = tmp->isp_osinfo.next;
198
199 for (chan = 0; chan < isp->isp_nchan; chan++) {
200 if (isp_attach_chan(isp, isp->isp_osinfo.devq, chan)) {
201 goto unwind;
242 }
202 }
243 tmp->isp_osinfo.next = isp;
244 }
245
203 }
204
246 /*
247 * Create a kernel thread for fibre channel instances.
248 */
249 if (IS_FC(isp)) {
250 isp_callout_init(&isp->isp_osinfo.ldt);
251 isp_callout_init(&isp->isp_osinfo.gdt);
252 ISP_UNLOCK(isp);
253#if __FreeBSD_version >= 500000
254 if (kproc_create(isp_kthread, isp, &isp->isp_osinfo.kproc,
255 RFHIGHPID, 0, "%s: fc_thrd",
256 device_get_nameunit(isp->isp_dev)))
257#else
258 if (kproc_create(isp_kthread, isp, &isp->isp_osinfo.kproc,
259 "%s: fc_thrd", device_get_nameunit(isp->isp_dev)))
260#endif
261 {
262 ISP_LOCK(isp);
263 xpt_bus_deregister(cam_sim_path(sim));
264 cam_sim_free(sim, TRUE);
265 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
266 isp_prt(isp, ISP_LOGERR, "could not create kthread");
267 return;
205 callout_init_mtx(&isp->isp_osinfo.tmo, &isp->isp_osinfo.lock, 0);
206 callout_reset(&isp->isp_osinfo.tmo, hz, isp_timer, isp);
207 isp->isp_osinfo.timer_active = 1;
208
209 isp->isp_osinfo.cdev = make_dev(&isp_cdevsw, du, UID_ROOT, GID_OPERATOR, 0600, "%s", nu);
210 if (isp->isp_osinfo.cdev) {
211 isp->isp_osinfo.cdev->si_drv1 = isp;
212 }
213 return (0);
214
215unwind:
216 while (--chan >= 0) {
217 struct cam_sim *sim;
218 struct cam_path *path;
219 if (IS_FC(isp)) {
220 sim = ISP_FC_PC(isp, chan)->sim;
221 path = ISP_FC_PC(isp, chan)->path;
222 } else {
223 sim = ISP_SPI_PC(isp, chan)->sim;
224 path = ISP_SPI_PC(isp, chan)->path;
268 }
225 }
226 xpt_free_path(path);
269 ISP_LOCK(isp);
227 ISP_LOCK(isp);
270 /*
271 * We start by being "loop down" if we have an initiator role
272 */
273 if (isp->isp_role & ISP_ROLE_INITIATOR) {
274 isp_freeze_loopdown(isp, "isp_attach");
275 isp->isp_osinfo.ldt_running = 1;
276 callout_reset(&isp->isp_osinfo.ldt,
277 isp_quickboot_time * hz, isp_ldt, isp);
278 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
279 "Starting Initial Loop Down Timer");
228 xpt_bus_deregister(cam_sim_path(sim));
229 ISP_UNLOCK(isp);
230 cam_sim_free(sim, FALSE);
231 }
232 if (isp->isp_osinfo.ehook_active) {
233 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
234 isp->isp_osinfo.ehook_active = 0;
235 }
236 if (isp->isp_osinfo.cdev) {
237 destroy_dev(isp->isp_osinfo.cdev);
238 isp->isp_osinfo.cdev = NULL;
239 }
240 cam_simq_free(isp->isp_osinfo.devq);
241 isp->isp_osinfo.devq = NULL;
242 return (-1);
243}
244
245void
246isp_detach(ispsoftc_t *isp)
247{
248 int chan;
249
250 ISP_LOCK(isp);
251 if (isp->isp_osinfo.timer_active) {
252 callout_stop(&isp->isp_osinfo.tmo);
253 isp->isp_osinfo.timer_active = 0;
254 }
255 ISP_UNLOCK(isp);
256 for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1) {
257 struct cam_sim *sim;
258 struct cam_path *path;
259 if (IS_FC(isp)) {
260 sim = ISP_FC_PC(isp, chan)->sim;
261 path = ISP_FC_PC(isp, chan)->path;
262 } else {
263 sim = ISP_SPI_PC(isp, chan)->sim;
264 path = ISP_SPI_PC(isp, chan)->path;
280 }
265 }
266 xpt_free_path(path);
267 ISP_LOCK(isp);
268 xpt_bus_deregister(cam_sim_path(sim));
269 ISP_UNLOCK(isp);
270 cam_sim_free(sim, FALSE);
281 }
271 }
272 if (isp->isp_osinfo.cdev) {
273 destroy_dev(isp->isp_osinfo.cdev);
274 isp->isp_osinfo.cdev = NULL;
275 }
276 if (isp->isp_osinfo.ehook_active) {
277 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
278 isp->isp_osinfo.ehook_active = 0;
279 }
280 if (isp->isp_osinfo.devq == NULL) {
281 cam_simq_free(isp->isp_osinfo.devq);
282 isp->isp_osinfo.devq = NULL;
283 }
282}
283
284static void
284}
285
286static void
285isp_freeze_loopdown(ispsoftc_t *isp, char *msg)
287isp_freeze_loopdown(ispsoftc_t *isp, int chan, char *msg)
286{
288{
287 if (isp->isp_osinfo.simqfrozen == 0) {
288 isp_prt(isp, ISP_LOGDEBUG0, "%s: freeze simq (loopdown)", msg);
289 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
290 xpt_freeze_simq(isp->isp_sim, 1);
291 } else {
292 isp_prt(isp, ISP_LOGDEBUG0, "%s: mark frozen (loopdown)", msg);
293 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
289 if (IS_FC(isp)) {
290 struct isp_fc *fc = ISP_FC_PC(isp, chan);
291 if (fc->simqfrozen == 0) {
292 isp_prt(isp, ISP_LOGDEBUG0, "%s: freeze simq (loopdown) chan %d", msg, chan);
293 fc->simqfrozen = SIMQFRZ_LOOPDOWN;
294 xpt_freeze_simq(fc->sim, 1);
295 } else {
296 isp_prt(isp, ISP_LOGDEBUG0, "%s: mark frozen (loopdown) chan %d", msg, chan);
297 fc->simqfrozen |= SIMQFRZ_LOOPDOWN;
298 }
294 }
295}
296
297
299 }
300}
301
302
298#if __FreeBSD_version < 500000
299#define _DEV dev_t
300#define _IOP struct proc
301#else
302#define _IOP struct thread
303#define _DEV struct cdev *
304#endif
305
306static int
303static int
307ispioctl(_DEV dev, u_long c, caddr_t addr, int flags, _IOP *td)
304ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
308{
309 ispsoftc_t *isp;
305{
306 ispsoftc_t *isp;
310 int nr, retval = ENOTTY;
307 int nr, chan, retval = ENOTTY;
311
308
312 isp = isplist;
313 while (isp) {
314 if (dev2unit(dev) == device_get_unit(isp->isp_dev)) {
315 break;
316 }
317 isp = isp->isp_osinfo.next;
318 }
319 if (isp == NULL) {
320 return (ENXIO);
321 }
309 isp = dev->si_drv1;
322
323 switch (c) {
310
311 switch (c) {
324#ifdef ISP_FW_CRASH_DUMP
325 case ISP_GET_FW_CRASH_DUMP:
326 if (IS_FC(isp)) {
327 uint16_t *ptr = FCPARAM(isp)->isp_dump_data;
328 size_t sz;
329
330 retval = 0;
331 if (IS_2200(isp)) {
332 sz = QLA2200_RISC_IMAGE_DUMP_SIZE;
333 } else {
334 sz = QLA2300_RISC_IMAGE_DUMP_SIZE;
335 }
336 if (ptr && *ptr) {
337 void *uaddr = *((void **) addr);
338 if (copyout(ptr, uaddr, sz)) {
339 retval = EFAULT;
340 } else {
341 *ptr = 0;
342 }
343 } else {
344 retval = ENXIO;
345 }
346 }
347 break;
348 case ISP_FORCE_CRASH_DUMP:
349 if (IS_FC(isp)) {
350 ISP_LOCK(isp);
351 isp_freeze_loopdown(isp,
352 "ispioctl(ISP_FORCE_CRASH_DUMP)");
353 isp_fw_dump(isp);
354 isp_reinit(isp);
355 ISP_UNLOCK(isp);
356 retval = 0;
357 }
358 break;
359#endif
360 case ISP_SDBLEV:
361 {
362 int olddblev = isp->isp_dblev;
363 isp->isp_dblev = *(int *)addr;
364 *(int *)addr = olddblev;
365 retval = 0;
366 break;
367 }
368 case ISP_GETROLE:
312 case ISP_SDBLEV:
313 {
314 int olddblev = isp->isp_dblev;
315 isp->isp_dblev = *(int *)addr;
316 *(int *)addr = olddblev;
317 retval = 0;
318 break;
319 }
320 case ISP_GETROLE:
369 *(int *)addr = isp->isp_role;
321 chan = *(int *)addr;
322 if (chan < 0 || chan >= isp->isp_nchan) {
323 retval = -ENXIO;
324 break;
325 }
326 if (IS_FC(isp)) {
327 *(int *)addr = FCPARAM(isp, chan)->role;
328 } else {
329 *(int *)addr = SDPARAM(isp, chan)->role;
330 }
370 retval = 0;
371 break;
372 case ISP_SETROLE:
373 nr = *(int *)addr;
331 retval = 0;
332 break;
333 case ISP_SETROLE:
334 nr = *(int *)addr;
335 chan = nr >> 8;
336 if (chan < 0 || chan >= isp->isp_nchan) {
337 retval = -ENXIO;
338 break;
339 }
340 nr &= 0xff;
374 if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
375 retval = EINVAL;
376 break;
377 }
341 if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
342 retval = EINVAL;
343 break;
344 }
378 *(int *)addr = isp->isp_role;
379 isp->isp_role = nr;
380 /* FALLTHROUGH */
345 if (IS_FC(isp)) {
346 *(int *)addr = FCPARAM(isp, chan)->role;
347#ifdef ISP_INTERNAL_TARGET
348 ISP_LOCK(isp);
349 retval = isp_fc_change_role(isp, chan, nr);
350 ISP_UNLOCK(isp);
351#else
352 FCPARAM(isp, chan)->role = nr;
353#endif
354 } else {
355 *(int *)addr = SDPARAM(isp, chan)->role;
356 SDPARAM(isp, chan)->role = nr;
357 }
358 retval = 0;
359 break;
360
381 case ISP_RESETHBA:
382 ISP_LOCK(isp);
361 case ISP_RESETHBA:
362 ISP_LOCK(isp);
383 isp_reinit(isp);
363#ifdef ISP_TARGET_MODE
364 isp_del_all_wwn_entries(isp, ISP_NOCHAN);
365#endif
366 isp_reinit(isp, 0);
384 ISP_UNLOCK(isp);
385 retval = 0;
386 break;
367 ISP_UNLOCK(isp);
368 retval = 0;
369 break;
370
387 case ISP_RESCAN:
388 if (IS_FC(isp)) {
371 case ISP_RESCAN:
372 if (IS_FC(isp)) {
373 chan = *(int *)addr;
374 if (chan < 0 || chan >= isp->isp_nchan) {
375 retval = -ENXIO;
376 break;
377 }
389 ISP_LOCK(isp);
378 ISP_LOCK(isp);
390 if (isp_fc_runstate(isp, 5 * 1000000)) {
379 if (isp_fc_runstate(isp, chan, 5 * 1000000)) {
391 retval = EIO;
392 } else {
393 retval = 0;
394 }
395 ISP_UNLOCK(isp);
396 }
397 break;
380 retval = EIO;
381 } else {
382 retval = 0;
383 }
384 ISP_UNLOCK(isp);
385 }
386 break;
387
398 case ISP_FC_LIP:
399 if (IS_FC(isp)) {
388 case ISP_FC_LIP:
389 if (IS_FC(isp)) {
390 chan = *(int *)addr;
391 if (chan < 0 || chan >= isp->isp_nchan) {
392 retval = -ENXIO;
393 break;
394 }
400 ISP_LOCK(isp);
395 ISP_LOCK(isp);
401 if (isp_control(isp, ISPCTL_SEND_LIP, 0)) {
396 if (isp_control(isp, ISPCTL_SEND_LIP, chan)) {
402 retval = EIO;
403 } else {
404 retval = 0;
405 }
406 ISP_UNLOCK(isp);
407 }
408 break;
409 case ISP_FC_GETDINFO:
410 {
411 struct isp_fc_device *ifc = (struct isp_fc_device *) addr;
412 fcportdb_t *lp;
413
414 if (IS_SCSI(isp)) {
415 break;
416 }
417 if (ifc->loopid >= MAX_FC_TARG) {
418 retval = EINVAL;
419 break;
420 }
397 retval = EIO;
398 } else {
399 retval = 0;
400 }
401 ISP_UNLOCK(isp);
402 }
403 break;
404 case ISP_FC_GETDINFO:
405 {
406 struct isp_fc_device *ifc = (struct isp_fc_device *) addr;
407 fcportdb_t *lp;
408
409 if (IS_SCSI(isp)) {
410 break;
411 }
412 if (ifc->loopid >= MAX_FC_TARG) {
413 retval = EINVAL;
414 break;
415 }
421 lp = &FCPARAM(isp)->portdb[ifc->loopid];
422 if (lp->state == FC_PORTDB_STATE_VALID) {
416 lp = &FCPARAM(isp, ifc->chan)->portdb[ifc->loopid];
417 if (lp->state == FC_PORTDB_STATE_VALID || lp->target_mode) {
423 ifc->role = lp->roles;
424 ifc->loopid = lp->handle;
425 ifc->portid = lp->portid;
426 ifc->node_wwn = lp->node_wwn;
427 ifc->port_wwn = lp->port_wwn;
428 retval = 0;
429 } else {
430 retval = ENODEV;
431 }
432 break;
433 }
434 case ISP_GET_STATS:
435 {
436 isp_stats_t *sp = (isp_stats_t *) addr;
437
418 ifc->role = lp->roles;
419 ifc->loopid = lp->handle;
420 ifc->portid = lp->portid;
421 ifc->node_wwn = lp->node_wwn;
422 ifc->port_wwn = lp->port_wwn;
423 retval = 0;
424 } else {
425 retval = ENODEV;
426 }
427 break;
428 }
429 case ISP_GET_STATS:
430 {
431 isp_stats_t *sp = (isp_stats_t *) addr;
432
438 MEMZERO(sp, sizeof (*sp));
433 ISP_MEMZERO(sp, sizeof (*sp));
439 sp->isp_stat_version = ISP_STATS_VERSION;
440 sp->isp_type = isp->isp_type;
441 sp->isp_revision = isp->isp_revision;
442 ISP_LOCK(isp);
443 sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt;
444 sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
445 sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
446 sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;

--- 16 unchanged lines hidden (view full) ---

463 isp->isp_rscchiwater = 0;
464 isp->isp_fpcchiwater = 0;
465 ISP_UNLOCK(isp);
466 retval = 0;
467 break;
468 case ISP_FC_GETHINFO:
469 {
470 struct isp_hba_device *hba = (struct isp_hba_device *) addr;
434 sp->isp_stat_version = ISP_STATS_VERSION;
435 sp->isp_type = isp->isp_type;
436 sp->isp_revision = isp->isp_revision;
437 ISP_LOCK(isp);
438 sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt;
439 sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
440 sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
441 sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;

--- 16 unchanged lines hidden (view full) ---

458 isp->isp_rscchiwater = 0;
459 isp->isp_fpcchiwater = 0;
460 ISP_UNLOCK(isp);
461 retval = 0;
462 break;
463 case ISP_FC_GETHINFO:
464 {
465 struct isp_hba_device *hba = (struct isp_hba_device *) addr;
471 MEMZERO(hba, sizeof (*hba));
466 int chan = hba->fc_channel;
472
467
468 if (chan < 0 || chan >= isp->isp_nchan) {
469 retval = ENXIO;
470 break;
471 }
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);
472 hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev);
473 hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev);
474 hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev);
475 hba->fc_nchannels = isp->isp_nchan;
476 if (IS_FC(isp)) {
476 if (IS_FC(isp)) {
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);
477 hba->fc_nports = MAX_FC_TARG;
478 hba->fc_speed = FCPARAM(isp, hba->fc_channel)->isp_gbspeed;
479 hba->fc_topology = FCPARAM(isp, chan)->isp_topo + 1;
480 hba->fc_loopid = FCPARAM(isp, chan)->isp_loopid;
481 hba->nvram_node_wwn = FCPARAM(isp, chan)->isp_wwnn_nvram;
482 hba->nvram_port_wwn = FCPARAM(isp, chan)->isp_wwpn_nvram;
483 hba->active_node_wwn = FCPARAM(isp, chan)->isp_wwnn;
484 hba->active_port_wwn = FCPARAM(isp, chan)->isp_wwpn;
485 } else {
486 hba->fc_nports = MAX_TARGETS;
487 hba->fc_speed = 0;
488 hba->fc_topology = 0;
489 hba->nvram_node_wwn = 0ull;
490 hba->nvram_port_wwn = 0ull;
491 hba->active_node_wwn = 0ull;
492 hba->active_port_wwn = 0ull;
485 }
486 retval = 0;
487 break;
488 }
489 case ISP_TSK_MGMT:
490 {
491 int needmarker;
492 struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
493 uint16_t loopid;
494 mbreg_t mbs;
495
496 if (IS_SCSI(isp)) {
497 break;
498 }
499
493 }
494 retval = 0;
495 break;
496 }
497 case ISP_TSK_MGMT:
498 {
499 int needmarker;
500 struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
501 uint16_t loopid;
502 mbreg_t mbs;
503
504 if (IS_SCSI(isp)) {
505 break;
506 }
507
500 memset(&mbs, 0, sizeof (mbs));
501 needmarker = retval = 0;
502 loopid = fct->loopid;
503 if (FCPARAM(isp)->isp_2klogin == 0) {
504 loopid <<= 8;
505 }
506 switch (fct->action) {
507 case IPT_CLEAR_ACA:
508 mbs.param[0] = MBOX_CLEAR_ACA;
509 mbs.param[1] = loopid;
510 mbs.param[2] = fct->lun;
508 chan = fct->chan;
509 if (chan < 0 || chan >= isp->isp_nchan) {
510 retval = -ENXIO;
511 break;
511 break;
512 case IPT_TARGET_RESET:
513 mbs.param[0] = MBOX_TARGET_RESET;
514 mbs.param[1] = loopid;
515 needmarker = 1;
516 break;
517 case IPT_LUN_RESET:
518 mbs.param[0] = MBOX_LUN_RESET;
519 mbs.param[1] = loopid;
520 mbs.param[2] = fct->lun;
521 needmarker = 1;
522 break;
523 case IPT_CLEAR_TASK_SET:
524 mbs.param[0] = MBOX_CLEAR_TASK_SET;
525 mbs.param[1] = loopid;
526 mbs.param[2] = fct->lun;
527 needmarker = 1;
528 break;
529 case IPT_ABORT_TASK_SET:
530 mbs.param[0] = MBOX_ABORT_TASK_SET;
531 mbs.param[1] = loopid;
532 mbs.param[2] = fct->lun;
533 needmarker = 1;
534 break;
535 default:
536 retval = EINVAL;
537 break;
538 }
512 }
539 if (retval == 0) {
540 if (needmarker) {
541 isp->isp_sendmarker |= 1;
513
514 needmarker = retval = 0;
515 loopid = fct->loopid;
516 ISP_LOCK(isp);
517 if (IS_24XX(isp)) {
518 uint8_t local[QENTRY_LEN];
519 isp24xx_tmf_t *tmf;
520 isp24xx_statusreq_t *sp;
521 fcparam *fcp = FCPARAM(isp, chan);
522 fcportdb_t *lp;
523 int i;
524
525 for (i = 0; i < MAX_FC_TARG; i++) {
526 lp = &fcp->portdb[i];
527 if (lp->handle == loopid) {
528 break;
529 }
542 }
530 }
543 ISP_LOCK(isp);
531 if (i == MAX_FC_TARG) {
532 retval = ENXIO;
533 ISP_UNLOCK(isp);
534 break;
535 }
536 /* XXX VALIDATE LP XXX */
537 tmf = (isp24xx_tmf_t *) local;
538 ISP_MEMZERO(tmf, QENTRY_LEN);
539 tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
540 tmf->tmf_header.rqs_entry_count = 1;
541 tmf->tmf_nphdl = lp->handle;
542 tmf->tmf_delay = 2;
543 tmf->tmf_timeout = 2;
544 tmf->tmf_tidlo = lp->portid;
545 tmf->tmf_tidhi = lp->portid >> 16;
546 tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
547 tmf->tmf_lun[1] = fct->lun & 0xff;
548 if (fct->lun >= 256) {
549 tmf->tmf_lun[0] = 0x40 | (fct->lun >> 8);
550 }
551 switch (fct->action) {
552 case IPT_CLEAR_ACA:
553 tmf->tmf_flags = ISP24XX_TMF_CLEAR_ACA;
554 break;
555 case IPT_TARGET_RESET:
556 tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
557 needmarker = 1;
558 break;
559 case IPT_LUN_RESET:
560 tmf->tmf_flags = ISP24XX_TMF_LUN_RESET;
561 needmarker = 1;
562 break;
563 case IPT_CLEAR_TASK_SET:
564 tmf->tmf_flags = ISP24XX_TMF_CLEAR_TASK_SET;
565 needmarker = 1;
566 break;
567 case IPT_ABORT_TASK_SET:
568 tmf->tmf_flags = ISP24XX_TMF_ABORT_TASK_SET;
569 needmarker = 1;
570 break;
571 default:
572 retval = EINVAL;
573 break;
574 }
575 if (retval) {
576 ISP_UNLOCK(isp);
577 break;
578 }
579 MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
580 mbs.param[1] = QENTRY_LEN;
581 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
582 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
583 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
584 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
585
586 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
587 ISP_UNLOCK(isp);
588 retval = ENOMEM;
589 break;
590 }
591 isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
592 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
593 sp = (isp24xx_statusreq_t *) local;
594 sp->req_completion_status = 1;
544 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
595 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
545 ISP_UNLOCK(isp);
546 if (retval)
596 MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN);
597 isp_get_24xx_response(isp, &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
598 FC_SCRATCH_RELEASE(isp, chan);
599 if (retval || sp->req_completion_status != 0) {
600 FC_SCRATCH_RELEASE(isp, chan);
547 retval = EIO;
601 retval = EIO;
602 }
603 if (retval == 0) {
604 if (needmarker) {
605 fcp->sendmarker = 1;
606 }
607 }
608 } else {
609 MBSINIT(&mbs, 0, MBLOGALL, 0);
610 if (ISP_CAP_2KLOGIN(isp) == 0) {
611 loopid <<= 8;
612 }
613 switch (fct->action) {
614 case IPT_CLEAR_ACA:
615 mbs.param[0] = MBOX_CLEAR_ACA;
616 mbs.param[1] = loopid;
617 mbs.param[2] = fct->lun;
618 break;
619 case IPT_TARGET_RESET:
620 mbs.param[0] = MBOX_TARGET_RESET;
621 mbs.param[1] = loopid;
622 needmarker = 1;
623 break;
624 case IPT_LUN_RESET:
625 mbs.param[0] = MBOX_LUN_RESET;
626 mbs.param[1] = loopid;
627 mbs.param[2] = fct->lun;
628 needmarker = 1;
629 break;
630 case IPT_CLEAR_TASK_SET:
631 mbs.param[0] = MBOX_CLEAR_TASK_SET;
632 mbs.param[1] = loopid;
633 mbs.param[2] = fct->lun;
634 needmarker = 1;
635 break;
636 case IPT_ABORT_TASK_SET:
637 mbs.param[0] = MBOX_ABORT_TASK_SET;
638 mbs.param[1] = loopid;
639 mbs.param[2] = fct->lun;
640 needmarker = 1;
641 break;
642 default:
643 retval = EINVAL;
644 break;
645 }
646 if (retval == 0) {
647 if (needmarker) {
648 FCPARAM(isp, chan)->sendmarker = 1;
649 }
650 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
651 if (retval) {
652 retval = EIO;
653 }
654 }
548 }
655 }
656 ISP_UNLOCK(isp);
549 break;
550 }
551 default:
552 break;
553 }
554 return (retval);
555}
556
657 break;
658 }
659 default:
660 break;
661 }
662 return (retval);
663}
664
557#if __FreeBSD_version >= 500000
558static void
665static void
559isp_sysctl_update(ispsoftc_t *isp)
560{
561 struct sysctl_ctx_list *ctx =
562 device_get_sysctl_ctx(isp->isp_osinfo.dev);
563 struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev);
564
565 if (IS_SCSI(isp)) {
566 return;
567 }
568
569 snprintf(isp->isp_osinfo.sysctl_info.fc.wwnn,
570 sizeof (isp->isp_osinfo.sysctl_info.fc.wwnn), "0x%08x%08x",
571 (uint32_t) (ISP_NODEWWN(isp) >> 32), (uint32_t) ISP_NODEWWN(isp));
572
573 snprintf(isp->isp_osinfo.sysctl_info.fc.wwpn,
574 sizeof (isp->isp_osinfo.sysctl_info.fc.wwpn), "0x%08x%08x",
575 (uint32_t) (ISP_PORTWWN(isp) >> 32), (uint32_t) ISP_PORTWWN(isp));
576
577 SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
578 "wwnn", CTLFLAG_RD, isp->isp_osinfo.sysctl_info.fc.wwnn, 0,
579 "World Wide Node Name");
580
581 SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
582 "wwpn", CTLFLAG_RD, isp->isp_osinfo.sysctl_info.fc.wwpn, 0,
583 "World Wide Port Name");
584
585 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
586 "loop_down_limit",
587 CTLFLAG_RW, &isp->isp_osinfo.loop_down_limit, 0,
588 "How long to wait for loop to come back up");
589
590 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
591 "gone_device_time",
592 CTLFLAG_RW, &isp->isp_osinfo.gone_device_time, 0,
593 "How long to wait for a device to reappear");
594}
595#endif
596
597static void
598isp_intr_enable(void *arg)
599{
666isp_intr_enable(void *arg)
667{
668 int chan;
600 ispsoftc_t *isp = arg;
601 ISP_LOCK(isp);
669 ispsoftc_t *isp = arg;
670 ISP_LOCK(isp);
602 if (isp->isp_role != ISP_ROLE_NONE) {
603 ISP_ENABLE_INTS(isp);
671 for (chan = 0; chan < isp->isp_nchan; chan++) {
672 if (IS_FC(isp)) {
673 if (FCPARAM(isp, chan)->role != ISP_ROLE_NONE) {
674 ISP_ENABLE_INTS(isp);
675 break;
676 }
677 } else {
678 if (SDPARAM(isp, chan)->role != ISP_ROLE_NONE) {
679 ISP_ENABLE_INTS(isp);
680 break;
681 }
682 }
604 }
605 ISP_UNLOCK(isp);
606 /* Release our hook so that the boot can continue. */
607 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
608}
609
610/*
683 }
684 ISP_UNLOCK(isp);
685 /* Release our hook so that the boot can continue. */
686 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
687}
688
689/*
690 * Local Inlines
691 */
692
693static ISP_INLINE int isp_get_pcmd(ispsoftc_t *, union ccb *);
694static ISP_INLINE void isp_free_pcmd(ispsoftc_t *, union ccb *);
695
696static ISP_INLINE int
697isp_get_pcmd(ispsoftc_t *isp, union ccb *ccb)
698{
699 ISP_PCMD(ccb) = isp->isp_osinfo.pcmd_free;
700 if (ISP_PCMD(ccb) == NULL) {
701 return (-1);
702 }
703 isp->isp_osinfo.pcmd_free = ((struct isp_pcmd *)ISP_PCMD(ccb))->next;
704 return (0);
705}
706
707static ISP_INLINE void
708isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb)
709{
710 ((struct isp_pcmd *)ISP_PCMD(ccb))->next = isp->isp_osinfo.pcmd_free;
711 isp->isp_osinfo.pcmd_free = ISP_PCMD(ccb);
712 ISP_PCMD(ccb) = NULL;
713}
714/*
611 * Put the target mode functions here, because some are inlines
612 */
613
614#ifdef ISP_TARGET_MODE
715 * Put the target mode functions here, because some are inlines
716 */
717
718#ifdef ISP_TARGET_MODE
615
616static __inline int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
617static __inline int are_any_luns_enabled(ispsoftc_t *, int);
618static __inline tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
619static __inline void rls_lun_statep(ispsoftc_t *, tstate_t *);
620static __inline atio_private_data_t *isp_get_atpd(ispsoftc_t *, int);
621static cam_status
622create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
719static ISP_INLINE int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
720static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
721static ISP_INLINE tstate_t *get_lun_statep_from_tag(ispsoftc_t *, int, uint32_t);
722static ISP_INLINE void rls_lun_statep(ispsoftc_t *, tstate_t *);
723static ISP_INLINE inot_private_data_t *get_ntp_from_tagdata(ispsoftc_t *, uint32_t, uint32_t, tstate_t **);
724static ISP_INLINE atio_private_data_t *isp_get_atpd(ispsoftc_t *, tstate_t *, uint32_t);
725static ISP_INLINE void isp_put_atpd(ispsoftc_t *, tstate_t *, atio_private_data_t *);
726static ISP_INLINE inot_private_data_t *isp_get_ntpd(ispsoftc_t *, tstate_t *);
727static ISP_INLINE inot_private_data_t *isp_find_ntpd(ispsoftc_t *, tstate_t *, uint32_t, uint32_t);
728static ISP_INLINE void isp_put_ntpd(ispsoftc_t *, tstate_t *, inot_private_data_t *);
729static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
623static void destroy_lun_state(ispsoftc_t *, tstate_t *);
730static void destroy_lun_state(ispsoftc_t *, tstate_t *);
624static int isp_en_lun(ispsoftc_t *, union ccb *);
731static void isp_enable_lun(ispsoftc_t *, union ccb *);
732static void isp_enable_deferred_luns(ispsoftc_t *, int);
733static cam_status isp_enable_deferred(ispsoftc_t *, int, lun_id_t);
734static void isp_disable_lun(ispsoftc_t *, union ccb *);
735static int isp_enable_target_mode(ispsoftc_t *, int);
625static void isp_ledone(ispsoftc_t *, lun_entry_t *);
736static void isp_ledone(ispsoftc_t *, lun_entry_t *);
626static cam_status isp_abort_tgt_ccb(ispsoftc_t *, union ccb *);
627static timeout_t isp_refire_putback_atio;
628static void isp_complete_ctio(union ccb *);
629static void isp_target_putback_atio(union ccb *);
630static void isp_target_start_ctio(ispsoftc_t *, union ccb *);
737static timeout_t isp_refire_putback_atio;
738static void isp_complete_ctio(union ccb *);
739static void isp_target_putback_atio(union ccb *);
740static void isp_target_start_ctio(ispsoftc_t *, union ccb *);
631static int isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
632static int isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
633static int isp_handle_platform_ctio(ispsoftc_t *, void *);
634static int isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *);
635static int isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
741static void isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
742static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
743static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
744static void isp_handle_platform_ctio(ispsoftc_t *, void *);
745static void isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *);
746static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
747static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
748static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *);
749static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
750static void isp_target_mark_aborted(ispsoftc_t *, union ccb *);
751static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t);
636
752
637static __inline int
753static ISP_INLINE int
638is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
639{
640 tstate_t *tptr;
754is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
755{
756 tstate_t *tptr;
641 tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
642 if (tptr == NULL) {
643 return (0);
644 }
645 do {
646 if (tptr->lun == (lun_id_t) lun && tptr->bus == bus) {
757 struct tslist *lhp;
758
759 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
760 SLIST_FOREACH(tptr, lhp, next) {
761 if (xpt_path_lun_id(tptr->owner) == lun) {
647 return (1);
648 }
762 return (1);
763 }
649 } while ((tptr = tptr->next) != NULL);
764 }
650 return (0);
651}
652
765 return (0);
766}
767
653static __inline int
654are_any_luns_enabled(ispsoftc_t *isp, int port)
768static void
769dump_tstates(ispsoftc_t *isp, int bus)
655{
770{
656 int lo, hi;
657 if (IS_DUALBUS(isp)) {
658 lo = (port * (LUN_HASH_SIZE >> 1));
659 hi = lo + (LUN_HASH_SIZE >> 1);
660 } else {
661 lo = 0;
662 hi = LUN_HASH_SIZE;
771 int i, j;
772 struct tslist *lhp;
773 tstate_t *tptr = NULL;
774
775 if (bus >= isp->isp_nchan) {
776 return;
663 }
777 }
664 for (lo = 0; lo < hi; lo++) {
665 if (isp->isp_osinfo.lun_hash[lo]) {
666 return (1);
778 for (i = 0; i < LUN_HASH_SIZE; i++) {
779 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
780 j = 0;
781 SLIST_FOREACH(tptr, lhp, next) {
782 xpt_print(tptr->owner, "[%d, %d] atio_cnt=%d inot_cnt=%d\n", i, j, tptr->atio_count, tptr->inot_count);
783 j++;
667 }
668 }
784 }
785 }
669 return (0);
670}
671
786}
787
672static __inline tstate_t *
788static ISP_INLINE tstate_t *
673get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
674{
675 tstate_t *tptr = NULL;
789get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
790{
791 tstate_t *tptr = NULL;
792 struct tslist *lhp;
793 int i;
676
794
677 if (lun == CAM_LUN_WILDCARD) {
678 if (isp->isp_osinfo.tmflags[bus] & TM_WILDCARD_ENABLED) {
679 tptr = &isp->isp_osinfo.tsdflt[bus];
680 tptr->hold++;
681 return (tptr);
795 if (bus < isp->isp_nchan) {
796 for (i = 0; i < LUN_HASH_SIZE; i++) {
797 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
798 SLIST_FOREACH(tptr, lhp, next) {
799 if (xpt_path_lun_id(tptr->owner) == lun) {
800 tptr->hold++;
801 return (tptr);
802 }
803 }
682 }
804 }
683 return (NULL);
684 } else {
685 tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
686 if (tptr == NULL) {
687 return (NULL);
688 }
689 }
805 }
806 return (NULL);
807}
690
808
691 do {
692 if (tptr->lun == lun && tptr->bus == bus) {
693 tptr->hold++;
694 return (tptr);
809static ISP_INLINE tstate_t *
810get_lun_statep_from_tag(ispsoftc_t *isp, int bus, uint32_t tagval)
811{
812 tstate_t *tptr = NULL;
813 atio_private_data_t *atp;
814 struct tslist *lhp;
815 int i;
816
817 if (bus < isp->isp_nchan && tagval != 0) {
818 for (i = 0; i < LUN_HASH_SIZE; i++) {
819 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
820 SLIST_FOREACH(tptr, lhp, next) {
821 atp = isp_get_atpd(isp, tptr, tagval);
822 if (atp && atp->tag == tagval) {
823 tptr->hold++;
824 return (tptr);
825 }
826 }
695 }
827 }
696 } while ((tptr = tptr->next) != NULL);
697 return (tptr);
828 }
829 return (NULL);
698}
699
830}
831
700static __inline void
832static ISP_INLINE inot_private_data_t *
833get_ntp_from_tagdata(ispsoftc_t *isp, uint32_t tag_id, uint32_t seq_id, tstate_t **rslt)
834{
835 inot_private_data_t *ntp;
836 tstate_t *tptr;
837 struct tslist *lhp;
838 int bus, i;
839
840 for (bus = 0; bus < isp->isp_nchan; bus++) {
841 for (i = 0; i < LUN_HASH_SIZE; i++) {
842 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
843 SLIST_FOREACH(tptr, lhp, next) {
844 ntp = isp_find_ntpd(isp, tptr, tag_id, seq_id);
845 if (ntp) {
846 *rslt = tptr;
847 tptr->hold++;
848 return (ntp);
849 }
850 }
851 }
852 }
853 return (NULL);
854}
855static ISP_INLINE void
701rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
702{
856rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
857{
703 if (tptr->hold)
704 tptr->hold--;
858 KASSERT((tptr->hold), ("tptr not held"));
859 tptr->hold--;
705}
706
860}
861
707static __inline atio_private_data_t *
708isp_get_atpd(ispsoftc_t *isp, int tag)
862static void
863isp_tmcmd_restart(ispsoftc_t *isp)
709{
864{
865 inot_private_data_t *ntp;
866 tstate_t *tptr;
867 struct tslist *lhp;
868 int bus, i;
869
870 for (bus = 0; bus < isp->isp_nchan; bus++) {
871 for (i = 0; i < LUN_HASH_SIZE; i++) {
872 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
873 SLIST_FOREACH(tptr, lhp, next) {
874 inot_private_data_t *restart_queue = tptr->restart_queue;
875 tptr->restart_queue = NULL;
876 while (restart_queue) {
877 ntp = restart_queue;
878 restart_queue = ntp->rd.nt.nt_hba;
879 if (IS_24XX(isp)) {
880 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid);
881 isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data);
882 } else {
883 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid);
884 isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data);
885 }
886 isp_put_ntpd(isp, tptr, ntp);
887 if (tptr->restart_queue && restart_queue != NULL) {
888 ntp = tptr->restart_queue;
889 tptr->restart_queue = restart_queue;
890 while (restart_queue->rd.nt.nt_hba) {
891 restart_queue = restart_queue->rd.nt.nt_hba;
892 }
893 restart_queue->rd.nt.nt_hba = ntp;
894 break;
895 }
896 }
897 }
898 }
899 }
900}
901
902static ISP_INLINE atio_private_data_t *
903isp_get_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag)
904{
710 atio_private_data_t *atp;
905 atio_private_data_t *atp;
711 for (atp = isp->isp_osinfo.atpdp;
712 atp < &isp->isp_osinfo.atpdp[ATPDPSIZE]; atp++) {
713 if (atp->tag == tag)
906
907 if (tag == 0) {
908 atp = tptr->atfree;
909 if (atp) {
910 tptr->atfree = atp->next;
911 }
912 return (atp);
913 }
914 for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
915 if (atp->tag == tag) {
714 return (atp);
916 return (atp);
917 }
715 }
716 return (NULL);
717}
718
918 }
919 return (NULL);
920}
921
922static ISP_INLINE void
923isp_put_atpd(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp)
924{
925 atp->tag = 0;
926 atp->dead = 0;
927 atp->next = tptr->atfree;
928 tptr->atfree = atp;
929}
930
931static void
932isp_dump_atpd(ispsoftc_t *isp, tstate_t *tptr)
933{
934 atio_private_data_t *atp;
935 const char *states[8] = { "Free", "ATIO", "CAM", "CTIO", "LAST_CTIO", "PDON", "?6", "7" };
936
937 for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
938 if (atp->tag == 0) {
939 continue;
940 }
941 xpt_print(tptr->owner, "ATP: [0x%x] origdlen %u bytes_xfrd %u last_xfr %u lun %u nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s\n",
942 atp->tag, atp->orig_datalen, atp->bytes_xfered, atp->last_xframt, atp->lun, atp->nphdl, atp->sid, atp->portid, atp->oxid, states[atp->state & 0x7]);
943 }
944}
945
946
947static ISP_INLINE inot_private_data_t *
948isp_get_ntpd(ispsoftc_t *isp, tstate_t *tptr)
949{
950 inot_private_data_t *ntp;
951 ntp = tptr->ntfree;
952 if (ntp) {
953 tptr->ntfree = ntp->next;
954 }
955 return (ntp);
956}
957
958static ISP_INLINE inot_private_data_t *
959isp_find_ntpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id, uint32_t seq_id)
960{
961 inot_private_data_t *ntp;
962 for (ntp = tptr->ntpool; ntp < &tptr->ntpool[ATPDPSIZE]; ntp++) {
963 if (ntp->rd.tag_id == tag_id && ntp->rd.seq_id == seq_id) {
964 return (ntp);
965 }
966 }
967 return (NULL);
968}
969
970static ISP_INLINE void
971isp_put_ntpd(ispsoftc_t *isp, tstate_t *tptr, inot_private_data_t *ntp)
972{
973 ntp->rd.tag_id = ntp->rd.seq_id = 0;
974 ntp->next = tptr->ntfree;
975 tptr->ntfree = ntp;
976}
977
719static cam_status
978static cam_status
720create_lun_state(ispsoftc_t *isp, int bus,
721 struct cam_path *path, tstate_t **rslt)
979create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rslt)
722{
723 cam_status status;
724 lun_id_t lun;
980{
981 cam_status status;
982 lun_id_t lun;
725 int hfx;
726 tstate_t *tptr, *new;
983 struct tslist *lhp;
984 tstate_t *tptr;
985 int i;
727
728 lun = xpt_path_lun_id(path);
986
987 lun = xpt_path_lun_id(path);
729 if (lun >= ISP_MAX_LUNS(isp)) {
730 return (CAM_LUN_INVALID);
988 if (lun != CAM_LUN_WILDCARD) {
989 if (lun >= ISP_MAX_LUNS(isp)) {
990 return (CAM_LUN_INVALID);
991 }
731 }
732 if (is_lun_enabled(isp, bus, lun)) {
733 return (CAM_LUN_ALRDY_ENA);
734 }
992 }
993 if (is_lun_enabled(isp, bus, lun)) {
994 return (CAM_LUN_ALRDY_ENA);
995 }
735 new = (tstate_t *) malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
736 if (new == NULL) {
996 tptr = (tstate_t *) malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
997 if (tptr == NULL) {
737 return (CAM_RESRC_UNAVAIL);
738 }
998 return (CAM_RESRC_UNAVAIL);
999 }
739
740 status = xpt_create_path(&new->owner, NULL, xpt_path_path_id(path),
741 xpt_path_target_id(path), xpt_path_lun_id(path));
1000 status = xpt_create_path(&tptr->owner, NULL, xpt_path_path_id(path), xpt_path_target_id(path), lun);
742 if (status != CAM_REQ_CMP) {
1001 if (status != CAM_REQ_CMP) {
743 free(new, M_DEVBUF);
1002 free(tptr, M_DEVBUF);
744 return (status);
745 }
1003 return (status);
1004 }
746 new->bus = bus;
747 new->lun = lun;
748 SLIST_INIT(&new->atios);
749 SLIST_INIT(&new->inots);
750 new->hold = 1;
751
752 hfx = LUN_HASH_FUNC(isp, new->bus, new->lun);
753 tptr = isp->isp_osinfo.lun_hash[hfx];
754 if (tptr == NULL) {
755 isp->isp_osinfo.lun_hash[hfx] = new;
756 } else {
757 while (tptr->next)
758 tptr = tptr->next;
759 tptr->next = new;
1005 SLIST_INIT(&tptr->atios);
1006 SLIST_INIT(&tptr->inots);
1007 for (i = 0; i < ATPDPSIZE-1; i++) {
1008 tptr->atpool[i].next = &tptr->atpool[i+1];
1009 tptr->ntpool[i].next = &tptr->ntpool[i+1];
760 }
1010 }
761 *rslt = new;
1011 tptr->atfree = tptr->atpool;
1012 tptr->ntfree = tptr->ntpool;
1013 tptr->hold = 1;
1014 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(xpt_path_lun_id(tptr->owner))], lhp);
1015 SLIST_INSERT_HEAD(lhp, tptr, next);
1016 *rslt = tptr;
1017 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, path, "created tstate\n");
762 return (CAM_REQ_CMP);
763}
764
1018 return (CAM_REQ_CMP);
1019}
1020
765static __inline void
1021static ISP_INLINE void
766destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
767{
1022destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
1023{
768 int hfx;
769 tstate_t *lw, *pw;
770
771 if (tptr->hold) {
772 return;
773 }
774 hfx = LUN_HASH_FUNC(isp, tptr->bus, tptr->lun);
775 pw = isp->isp_osinfo.lun_hash[hfx];
776 if (pw == NULL) {
777 return;
778 } else if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
779 isp->isp_osinfo.lun_hash[hfx] = pw->next;
780 } else {
781 lw = pw;
782 pw = lw->next;
783 while (pw) {
784 if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
785 lw->next = pw->next;
786 break;
787 }
788 lw = pw;
789 pw = pw->next;
790 }
791 if (pw == NULL) {
792 return;
793 }
794 }
1024 struct tslist *lhp;
1025 KASSERT((tptr->hold == 0), ("tptr still held"));
1026 ISP_GET_PC_ADDR(isp, xpt_path_path_id(tptr->owner), lun_hash[LUN_HASH_FUNC(xpt_path_lun_id(tptr->owner))], lhp);
1027 SLIST_REMOVE(lhp, tptr, tstate, next);
1028 xpt_free_path(tptr->owner);
795 free(tptr, M_DEVBUF);
796}
797
798/*
1029 free(tptr, M_DEVBUF);
1030}
1031
1032/*
799 * Enable luns.
1033 * Enable a lun.
800 */
1034 */
801static int
802isp_en_lun(ispsoftc_t *isp, union ccb *ccb)
1035static void
1036isp_enable_lun(ispsoftc_t *isp, union ccb *ccb)
803{
1037{
804 struct ccb_en_lun *cel = &ccb->cel;
805 tstate_t *tptr = NULL;
1038 tstate_t *tptr = NULL;
806 uint32_t seq;
807 int bus, cmd, av, wildcard, tm_on;
1039 int bus, tm_enabled, target_role;
1040 target_id_t target;
808 lun_id_t lun;
1041 lun_id_t lun;
809 target_id_t tgt;
810
1042
1043 /*
1044 * We only support either a wildcard target/lun or a target ID of zero and a non-wildcard lun
1045 */
811 bus = XS_CHANNEL(ccb);
1046 bus = XS_CHANNEL(ccb);
812 if (bus > 1) {
813 xpt_print(ccb->ccb_h.path, "illegal bus %d\n", bus);
814 ccb->ccb_h.status = CAM_PATH_INVALID;
815 return (-1);
816 }
817 tgt = ccb->ccb_h.target_id;
1047 target = ccb->ccb_h.target_id;
818 lun = ccb->ccb_h.target_lun;
1048 lun = ccb->ccb_h.target_lun;
1049 if (target != CAM_TARGET_WILDCARD && target != 0) {
1050 ccb->ccb_h.status = CAM_TID_INVALID;
1051 xpt_done(ccb);
1052 return;
1053 }
1054 if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
1055 ccb->ccb_h.status = CAM_LUN_INVALID;
1056 xpt_done(ccb);
1057 return;
1058 }
819
1059
1060 if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
1061 ccb->ccb_h.status = CAM_LUN_INVALID;
1062 xpt_done(ccb);
1063 return;
1064 }
820 if (isp->isp_dblev & ISP_LOGTDEBUG0) {
1065 if (isp->isp_dblev & ISP_LOGTDEBUG0) {
821 xpt_print(ccb->ccb_h.path, "%sabling lun 0x%x on channel %d\n",
822 cel->enable? "en" : "dis", lun, bus);
1066 xpt_print(ccb->ccb_h.path, "enabling lun 0x%x on channel %d\n", lun, bus);
823 }
824
1067 }
1068
825 if ((lun != CAM_LUN_WILDCARD) &&
826 (lun >= (lun_id_t) isp->isp_maxluns)) {
827 ccb->ccb_h.status = CAM_LUN_INVALID;
828 return (-1);
1069 /*
1070 * Wait until we're not busy with the lun enables subsystem
1071 */
1072 while (isp->isp_osinfo.tmbusy) {
1073 isp->isp_osinfo.tmwanted = 1;
1074 mtx_sleep(isp, &isp->isp_lock, PRIBIO, "want_isp_enable_lun", 0);
829 }
1075 }
1076 isp->isp_osinfo.tmbusy = 1;
830
1077
831 if (IS_SCSI(isp)) {
832 sdparam *sdp = isp->isp_param;
833 sdp += bus;
834 if (tgt != CAM_TARGET_WILDCARD &&
835 tgt != sdp->isp_initiator_id) {
836 ccb->ccb_h.status = CAM_TID_INVALID;
837 return (-1);
838 }
839 } else {
840 /*
841 * There's really no point in doing this yet w/o multi-tid
842 * capability. Even then, it's problematic.
843 */
844#if 0
845 if (tgt != CAM_TARGET_WILDCARD &&
846 tgt != FCPARAM(isp)->isp_iid) {
847 ccb->ccb_h.status = CAM_TID_INVALID;
848 return (-1);
849 }
850#endif
851 /*
852 * This is as a good a place as any to check f/w capabilities.
853 */
854 if (FCPARAM(isp)->isp_tmode == 0) {
855 xpt_print(ccb->ccb_h.path,
856 "firmware does not support target mode\n");
1078 /*
1079 * This is as a good a place as any to check f/w capabilities.
1080 */
1081
1082 if (IS_FC(isp)) {
1083 if (ISP_CAP_TMODE(isp) == 0) {
1084 xpt_print(ccb->ccb_h.path, "firmware does not support target mode\n");
857 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1085 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
858 return (-1);
1086 goto done;
859 }
860 /*
1087 }
1088 /*
861 * XXX: We *could* handle non-SCCLUN f/w, but we'd have to
862 * XXX: dork with our already fragile enable/disable code.
1089 * We *could* handle non-SCCLUN f/w, but we'd have to
1090 * dork with our already fragile enable/disable code.
863 */
1091 */
864 if (FCPARAM(isp)->isp_sccfw == 0) {
865 xpt_print(ccb->ccb_h.path,
866 "firmware not SCCLUN capable\n");
1092 if (ISP_CAP_SCCFW(isp) == 0) {
1093 xpt_print(ccb->ccb_h.path, "firmware not SCCLUN capable\n");
867 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1094 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
868 return (-1);
1095 goto done;
869 }
1096 }
870 }
871
1097
872 if (tgt == CAM_TARGET_WILDCARD) {
873 if (lun == CAM_LUN_WILDCARD) {
874 wildcard = 1;
875 } else {
876 ccb->ccb_h.status = CAM_LUN_INVALID;
877 return (-1);
878 }
1098 target_role = (FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) != 0;
1099
879 } else {
1100 } else {
880 wildcard = 0;
1101 target_role = (SDPARAM(isp, bus)->role & ISP_ROLE_TARGET) != 0;
881 }
882
1102 }
1103
883 tm_on = (isp->isp_osinfo.tmflags[bus] & TM_TMODE_ENABLED) != 0;
884
885 /*
1104 /*
886 * Next check to see whether this is a target/lun wildcard action.
887 *
888 * If so, we know that we can accept commands for luns that haven't
889 * been enabled yet and send them upstream. Otherwise, we have to
890 * handle them locally (if we see them at all).
1105 * Create the state pointer.
1106 * It should not already exist.
891 */
1107 */
892
893 if (wildcard) {
894 tptr = &isp->isp_osinfo.tsdflt[bus];
895 if (cel->enable) {
896 if (tm_on) {
897 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
898 return (-1);
899 }
900 ccb->ccb_h.status =
901 xpt_create_path(&tptr->owner, NULL,
902 xpt_path_path_id(ccb->ccb_h.path),
903 xpt_path_target_id(ccb->ccb_h.path),
904 xpt_path_lun_id(ccb->ccb_h.path));
905 if (ccb->ccb_h.status != CAM_REQ_CMP) {
906 return (-1);
907 }
908 SLIST_INIT(&tptr->atios);
909 SLIST_INIT(&tptr->inots);
910 isp->isp_osinfo.tmflags[bus] |= TM_WILDCARD_ENABLED;
911 } else {
912 if (tm_on == 0) {
913 ccb->ccb_h.status = CAM_REQ_CMP;
914 return (-1);
915 }
916 if (tptr->hold) {
917 ccb->ccb_h.status = CAM_SCSI_BUSY;
918 return (-1);
919 }
920 xpt_free_path(tptr->owner);
921 isp->isp_osinfo.tmflags[bus] &= ~TM_WILDCARD_ENABLED;
922 }
1108 tptr = get_lun_statep(isp, bus, lun);
1109 if (tptr) {
1110 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
1111 goto done;
923 }
1112 }
1113 ccb->ccb_h.status = create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
1114 if (ccb->ccb_h.status != CAM_REQ_CMP) {
1115 goto done;
1116 }
924
925 /*
1117
1118 /*
926 * Now check to see whether this bus needs to be
927 * enabled/disabled with respect to target mode.
1119 * We have a tricky maneuver to perform here.
1120 *
1121 * If target mode isn't already enabled here,
1122 * *and* our current role includes target mode,
1123 * we enable target mode here.
1124 *
928 */
1125 */
929 av = bus << 31;
930 if (cel->enable && tm_on == 0) {
931 av |= ENABLE_TARGET_FLAG;
932 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
933 if (av) {
934 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
935 if (wildcard) {
936 isp->isp_osinfo.tmflags[bus] &=
937 ~TM_WILDCARD_ENABLED;
938 xpt_free_path(tptr->owner);
939 }
940 return (-1);
1126 ISP_GET_PC(isp, bus, tm_enabled, tm_enabled);
1127 if (tm_enabled == 0 && target_role != 0) {
1128 if (isp_enable_target_mode(isp, bus)) {
1129 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1130 destroy_lun_state(isp, tptr);
1131 tptr = NULL;
1132 goto done;
941 }
1133 }
942 isp->isp_osinfo.tmflags[bus] |= TM_TMODE_ENABLED;
943 xpt_print(ccb->ccb_h.path, "Target Mode Enabled\n");
944 } else if (cel->enable == 0 && tm_on && wildcard) {
945 if (are_any_luns_enabled(isp, bus)) {
946 ccb->ccb_h.status = CAM_SCSI_BUSY;
947 return (-1);
948 }
949 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
950 if (av) {
951 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
952 return (-1);
953 }
954 isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
955 xpt_print(ccb->ccb_h.path, "Target Mode Disabled\n");
1134 tm_enabled = 1;
956 }
957
1135 }
1136
958 if (wildcard) {
1137 /*
1138 * Now check to see whether this bus is in target mode already.
1139 *
1140 * If not, a later role change into target mode will finish the job.
1141 */
1142 if (tm_enabled == 0) {
1143 ISP_SET_PC(isp, bus, tm_enable_defer, 1);
959 ccb->ccb_h.status = CAM_REQ_CMP;
1144 ccb->ccb_h.status = CAM_REQ_CMP;
960 return (-1);
1145 xpt_print(ccb->ccb_h.path, "Target Mode Not Enabled Yet- Lun Enables Deferred\n");
1146 goto done;
961 }
962
963 /*
1147 }
1148
1149 /*
964 * Find an empty slot
1150 * Enable the lun.
965 */
1151 */
966 for (seq = 0; seq < NLEACT; seq++) {
967 if (isp->isp_osinfo.leact[seq] == 0) {
968 break;
969 }
1152 ccb->ccb_h.status = isp_enable_deferred(isp, bus, lun);
1153
1154done:
1155 if (ccb->ccb_h.status != CAM_REQ_CMP && tptr) {
1156 destroy_lun_state(isp, tptr);
1157 tptr = NULL;
970 }
1158 }
971 if (seq >= NLEACT) {
972 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
973 return (-1);
974
1159 if (tptr) {
1160 rls_lun_statep(isp, tptr);
975 }
1161 }
976 isp->isp_osinfo.leact[seq] = ccb;
977
978 if (cel->enable) {
979 ccb->ccb_h.status =
980 create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
981 if (ccb->ccb_h.status != CAM_REQ_CMP) {
982 isp->isp_osinfo.leact[seq] = 0;
983 return (-1);
984 }
985 } else {
986 tptr = get_lun_statep(isp, bus, lun);
987 if (tptr == NULL) {
988 ccb->ccb_h.status = CAM_LUN_INVALID;
989 return (-1);
990 }
1162 isp->isp_osinfo.tmbusy = 0;
1163 if (isp->isp_osinfo.tmwanted) {
1164 isp->isp_osinfo.tmwanted = 0;
1165 wakeup(isp);
991 }
1166 }
1167 xpt_done(ccb);
1168}
992
1169
993 if (cel->enable) {
994 int c, n, ulun = lun;
1170static void
1171isp_enable_deferred_luns(ispsoftc_t *isp, int bus)
1172{
1173 /*
1174 * XXX: not entirely implemented yet
1175 */
1176 (void) isp_enable_deferred(isp, bus, 0);
1177}
995
1178
996 cmd = RQSTYPE_ENABLE_LUN;
997 c = DFLT_CMND_CNT;
998 n = DFLT_INOT_CNT;
999 if (IS_FC(isp) && lun != 0) {
1000 cmd = RQSTYPE_MODIFY_LUN;
1001 n = 0;
1002 /*
1003 * For SCC firmware, we only deal with setting
1004 * (enabling or modifying) lun 0.
1005 */
1006 ulun = 0;
1007 }
1008 if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
1009 rls_lun_statep(isp, tptr);
1010 ccb->ccb_h.status = CAM_REQ_INPROG;
1011 return (seq);
1012 }
1179static uint32_t
1180isp_enable_deferred(ispsoftc_t *isp, int bus, lun_id_t lun)
1181{
1182 cam_status status;
1183
1184 isp_prt(isp, ISP_LOGTINFO, "%s: bus %d lun %u", __func__, bus, lun);
1185 if (IS_24XX(isp) || (IS_FC(isp) && ISP_FC_PC(isp, bus)->tm_luns_enabled)) {
1186 status = CAM_REQ_CMP;
1013 } else {
1187 } else {
1014 int c, n, ulun = lun;
1188 int cmd_cnt, not_cnt;
1015
1189
1016 cmd = -RQSTYPE_MODIFY_LUN;
1017 c = DFLT_CMND_CNT;
1018 n = DFLT_INOT_CNT;
1019 if (IS_FC(isp) && lun != 0) {
1020 n = 0;
1021 /*
1022 * For SCC firmware, we only deal with setting
1023 * (enabling or modifying) lun 0.
1024 */
1025 ulun = 0;
1190 if (IS_23XX(isp)) {
1191 cmd_cnt = DFLT_CMND_CNT;
1192 not_cnt = DFLT_INOT_CNT;
1193 } else {
1194 cmd_cnt = 64;
1195 not_cnt = 8;
1026 }
1196 }
1027 if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
1028 rls_lun_statep(isp, tptr);
1029 ccb->ccb_h.status = CAM_REQ_INPROG;
1030 return (seq);
1197 status = CAM_REQ_INPROG;
1198 isp->isp_osinfo.rptr = &status;
1199 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, DFLT_CMND_CNT, DFLT_INOT_CNT)) {
1200 status = CAM_RESRC_UNAVAIL;
1201 } else {
1202 mtx_sleep(&status, &isp->isp_lock, PRIBIO, "isp_enable_deferred", 0);
1031 }
1203 }
1204 isp->isp_osinfo.rptr = NULL;
1032 }
1205 }
1033 rls_lun_statep(isp, tptr);
1034 xpt_print(ccb->ccb_h.path, "isp_lun_cmd failed\n");
1035 isp->isp_osinfo.leact[seq] = 0;
1036 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1037 return (-1);
1206
1207 if (status == CAM_REQ_CMP) {
1208 ISP_SET_PC(isp, bus, tm_luns_enabled, 1);
1209 isp_prt(isp, ISP_LOGTINFO, "bus %d lun %u now enabled for target mode", bus, lun);
1210 }
1211 return (status);
1038}
1039
1040static void
1212}
1213
1214static void
1041isp_ledone(ispsoftc_t *isp, lun_entry_t *lep)
1215isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
1042{
1216{
1043 const char lfmt[] = "now %sabled for target mode\n";
1044 union ccb *ccb;
1045 uint32_t seq;
1046 tstate_t *tptr;
1047 int av;
1048 struct ccb_en_lun *cel;
1217 tstate_t *tptr = NULL;
1218 int bus;
1219 cam_status status;
1220 target_id_t target;
1221 lun_id_t lun;
1049
1222
1050 seq = lep->le_reserved - 1;
1051 if (seq >= NLEACT) {
1052 isp_prt(isp, ISP_LOGERR,
1053 "seq out of range (%u) in isp_ledone", seq);
1223 bus = XS_CHANNEL(ccb);
1224 target = ccb->ccb_h.target_id;
1225 lun = ccb->ccb_h.target_lun;
1226 if (target != CAM_TARGET_WILDCARD && target != 0) {
1227 ccb->ccb_h.status = CAM_TID_INVALID;
1228 xpt_done(ccb);
1054 return;
1055 }
1229 return;
1230 }
1056 ccb = isp->isp_osinfo.leact[seq];
1057 if (ccb == 0) {
1058 isp_prt(isp, ISP_LOGERR,
1059 "no ccb for seq %u in isp_ledone", seq);
1231 if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
1232 ccb->ccb_h.status = CAM_LUN_INVALID;
1233 xpt_done(ccb);
1060 return;
1061 }
1234 return;
1235 }
1062 cel = &ccb->cel;
1063 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
1064 if (tptr == NULL) {
1065 xpt_print(ccb->ccb_h.path, "null tptr in isp_ledone\n");
1066 isp->isp_osinfo.leact[seq] = 0;
1067 return;
1068 }
1069
1236
1070 if (lep->le_status != LUN_OK) {
1071 xpt_print(ccb->ccb_h.path,
1072 "ENABLE/MODIFY LUN returned 0x%x\n", lep->le_status);
1073err:
1074 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1075 rls_lun_statep(isp, tptr);
1076 isp->isp_osinfo.leact[seq] = 0;
1237 if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
1238 ccb->ccb_h.status = CAM_LUN_INVALID;
1077 xpt_done(ccb);
1078 return;
1239 xpt_done(ccb);
1240 return;
1079 } else {
1080 isp_prt(isp, ISP_LOGTDEBUG0,
1081 "isp_ledone: ENABLE/MODIFY done okay");
1082 }
1241 }
1242 if (isp->isp_dblev & ISP_LOGTDEBUG0) {
1243 xpt_print(ccb->ccb_h.path, "enabling lun 0x%x on channel %d\n", lun, bus);
1244 }
1083
1245
1246 /*
1247 * See if we're busy disabling a lun now.
1248 */
1249 while (isp->isp_osinfo.tmbusy) {
1250 isp->isp_osinfo.tmwanted = 1;
1251 mtx_sleep(isp, &isp->isp_lock, PRIBIO, "want_isp_disable_lun", 0);
1252 }
1253 isp->isp_osinfo.tmbusy = 1;
1084
1254
1085 if (cel->enable) {
1086 ccb->ccb_h.status = CAM_REQ_CMP;
1087 xpt_print(ccb->ccb_h.path, lfmt, "en");
1088 rls_lun_statep(isp, tptr);
1089 isp->isp_osinfo.leact[seq] = 0;
1090 xpt_done(ccb);
1091 return;
1255 /*
1256 * Find the state pointer.
1257 */
1258 if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) {
1259 ccb->ccb_h.status = CAM_PATH_INVALID;
1260 goto done;
1092 }
1093
1261 }
1262
1094 if (lep->le_header.rqs_entry_type == RQSTYPE_MODIFY_LUN) {
1095 if (isp_lun_cmd(isp, -RQSTYPE_ENABLE_LUN, XS_CHANNEL(ccb),
1096 XS_TGT(ccb), XS_LUN(ccb), 0, 0, seq+1)) {
1097 xpt_print(ccb->ccb_h.path,
1098 "isp_ledone: isp_lun_cmd failed\n");
1099 goto err;
1100 }
1101 rls_lun_statep(isp, tptr);
1102 return;
1263 /*
1264 * If we're a 24XX card, we're done.
1265 */
1266 if (IS_24XX(isp)) {
1267 status = CAM_REQ_CMP;
1268 goto done;
1103 }
1104
1269 }
1270
1105 xpt_print(ccb->ccb_h.path, lfmt, "dis");
1106 rls_lun_statep(isp, tptr);
1107 destroy_lun_state(isp, tptr);
1108 ccb->ccb_h.status = CAM_REQ_CMP;
1109 isp->isp_osinfo.leact[seq] = 0;
1271 /*
1272 * For SCC FW, we only deal with lun zero.
1273 */
1274 if (IS_FC(isp)) {
1275 lun = 0;
1276 }
1277
1278 isp->isp_osinfo.rptr = &status;
1279 status = CAM_REQ_INPROG;
1280 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, 0, 0)) {
1281 status = CAM_RESRC_UNAVAIL;
1282 } else {
1283 mtx_sleep(ccb, &isp->isp_lock, PRIBIO, "isp_disable_lun", 0);
1284 }
1285done:
1286 if (status == CAM_REQ_CMP) {
1287 xpt_print(ccb->ccb_h.path, "now disabled for target mode\n");
1288 }
1289 if (tptr) {
1290 rls_lun_statep(isp, tptr);
1291 }
1292 isp->isp_osinfo.rptr = NULL;
1293 isp->isp_osinfo.tmbusy = 0;
1294 if (isp->isp_osinfo.tmwanted) {
1295 isp->isp_osinfo.tmwanted = 0;
1296 wakeup(isp);
1297 }
1110 xpt_done(ccb);
1298 xpt_done(ccb);
1111 if (are_any_luns_enabled(isp, XS_CHANNEL(ccb)) == 0) {
1112 int bus = XS_CHANNEL(ccb);
1113 av = bus << 31;
1114 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
1115 if (av) {
1116 isp_prt(isp, ISP_LOGWARN,
1117 "disable target mode on channel %d failed", bus);
1299}
1300
1301static int
1302isp_enable_target_mode(ispsoftc_t *isp, int bus)
1303{
1304 int ct;
1305
1306 ISP_GET_PC(isp, bus, tm_enabled, ct);
1307 if (ct != 0) {
1308 return (0);
1309 }
1310
1311 if (IS_SCSI(isp)) {
1312 mbreg_t mbs;
1313
1314 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
1315 mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
1316 mbs.param[1] = ENABLE_TARGET_FLAG|ENABLE_TQING_FLAG;
1317 mbs.param[2] = bus << 7;
1318 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1319 isp_prt(isp, ISP_LOGERR, "Unable to add Target Role to Bus %d", bus);
1320 return (EIO);
1118 }
1321 }
1119 isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
1322 SDPARAM(isp, bus)->role |= ISP_ROLE_TARGET;
1120 }
1323 }
1324 ISP_SET_PC(isp, bus, tm_enabled, 1);
1325 isp_prt(isp, ISP_LOGINFO, "Target Role added to Bus %d", bus);
1326 return (0);
1121}
1122
1327}
1328
1123
1124static cam_status
1125isp_abort_tgt_ccb(ispsoftc_t *isp, union ccb *ccb)
1329#ifdef NEEDED
1330static int
1331isp_disable_target_mode(ispsoftc_t *isp, int bus)
1126{
1332{
1127 tstate_t *tptr;
1128 struct ccb_hdr_slist *lp;
1129 struct ccb_hdr *curelm;
1130 int found, *ctr;
1131 union ccb *accb = ccb->cab.abort_ccb;
1333 int ct;
1132
1334
1133 xpt_print(ccb->ccb_h.path, "aborting ccb %p\n", accb);
1134 if (accb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
1135 int badpath = 0;
1136 if (IS_FC(isp) && (accb->ccb_h.target_id !=
1137 ((fcparam *) isp->isp_param)->isp_loopid)) {
1138 badpath = 1;
1139 } else if (IS_SCSI(isp) && (accb->ccb_h.target_id !=
1140 ((sdparam *) isp->isp_param)->isp_initiator_id)) {
1141 badpath = 1;
1335 ISP_GET_PC(isp, bus, tm_enabled, ct);
1336 if (ct == 0) {
1337 return (0);
1338 }
1339
1340 if (IS_SCSI(isp)) {
1341 mbreg_t mbs;
1342
1343 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
1344 mbs.param[2] = bus << 7;
1345 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1346 isp_prt(isp, ISP_LOGERR, "Unable to subtract Target Role to Bus %d", bus);
1347 return (EIO);
1142 }
1348 }
1143 if (badpath) {
1144 /*
1145 * Being restrictive about target ids is really about
1146 * making sure we're aborting for the right multi-tid
1147 * path. This doesn't really make much sense at present.
1148 */
1149#if 0
1150 return (CAM_PATH_INVALID);
1349 SDPARAM(isp, bus)->role &= ~ISP_ROLE_TARGET;
1350 }
1351 ISP_SET_PC(isp, bus, tm_enabled, 0);
1352 isp_prt(isp, ISP_LOGINFO, "Target Role subtracted from Bus %d", bus);
1353 return (0);
1354}
1151#endif
1355#endif
1356
1357static void
1358isp_ledone(ispsoftc_t *isp, lun_entry_t *lep)
1359{
1360 uint32_t *rptr;
1361
1362 rptr = isp->isp_osinfo.rptr;
1363 if (lep->le_status != LUN_OK) {
1364 isp_prt(isp, ISP_LOGERR, "ENABLE/MODIFY LUN returned 0x%x", lep->le_status);
1365 if (rptr) {
1366 *rptr = CAM_REQ_CMP_ERR;
1367 wakeup_one(rptr);
1152 }
1368 }
1153 }
1154 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), accb->ccb_h.target_lun);
1155 if (tptr == NULL) {
1156 xpt_print(ccb->ccb_h.path, "can't get statep\n");
1157 return (CAM_PATH_INVALID);
1158 }
1159 if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
1160 lp = &tptr->atios;
1161 ctr = &tptr->atio_count;
1162 } else if (accb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
1163 lp = &tptr->inots;
1164 ctr = &tptr->inot_count;
1165 } else {
1369 } else {
1166 rls_lun_statep(isp, tptr);
1167 xpt_print(ccb->ccb_h.path, "bad function code %d\n",
1168 accb->ccb_h.func_code);
1169 return (CAM_UA_ABORT);
1170 }
1171 curelm = SLIST_FIRST(lp);
1172 found = 0;
1173 if (curelm == &accb->ccb_h) {
1174 found = 1;
1175 SLIST_REMOVE_HEAD(lp, sim_links.sle);
1176 } else {
1177 while(curelm != NULL) {
1178 struct ccb_hdr *nextelm;
1179
1180 nextelm = SLIST_NEXT(curelm, sim_links.sle);
1181 if (nextelm == &accb->ccb_h) {
1182 found = 1;
1183 SLIST_NEXT(curelm, sim_links.sle) =
1184 SLIST_NEXT(nextelm, sim_links.sle);
1185 break;
1186 }
1187 curelm = nextelm;
1370 if (rptr) {
1371 *rptr = CAM_REQ_CMP;
1372 wakeup_one(rptr);
1188 }
1189 }
1373 }
1374 }
1190 rls_lun_statep(isp, tptr);
1191 if (found) {
1192 (*ctr)--;
1193 accb->ccb_h.status = CAM_REQ_ABORTED;
1194 xpt_done(accb);
1195 return (CAM_REQ_CMP);
1196 }
1197 xpt_print(ccb->ccb_h.path, "ccb %p not found\n", accb);
1198 return (CAM_PATH_INVALID);
1199}
1200
1201static void
1202isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
1203{
1204 void *qe;
1375}
1376
1377static void
1378isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
1379{
1380 void *qe;
1381 tstate_t *tptr;
1382 atio_private_data_t *atp;
1205 struct ccb_scsiio *cso = &ccb->csio;
1383 struct ccb_scsiio *cso = &ccb->csio;
1206 uint32_t nxti, optr, handle;
1384 uint32_t dmaresult, handle;
1207 uint8_t local[QENTRY_LEN];
1208
1385 uint8_t local[QENTRY_LEN];
1386
1387 /*
1388 * Do some sanity checks.
1389 */
1390 if (cso->dxfer_len == 0) {
1391 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) {
1392 xpt_print(ccb->ccb_h.path, "a data transfer length of zero but no status to send is wrong\n");
1393 ccb->ccb_h.status = CAM_REQ_INVALID;
1394 xpt_done(ccb);
1395 return;
1396 }
1397 }
1209
1398
1210 if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
1211 xpt_print(ccb->ccb_h.path,
1212 "Request Queue Overflow in isp_target_start_ctio\n");
1213 XS_SETERR(ccb, CAM_REQUEUE_REQ);
1399 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
1400 if (tptr == NULL) {
1401 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
1402 if (tptr == NULL) {
1403 xpt_print(ccb->ccb_h.path, "%s: [0x%x] cannot find tstate pointer in %s\n", __func__, cso->tag_id);
1404 dump_tstates(isp, XS_CHANNEL(ccb));
1405 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1406 xpt_done(ccb);
1407 return;
1408 }
1409 }
1410
1411 atp = isp_get_atpd(isp, tptr, cso->tag_id);
1412 if (atp == NULL) {
1413 xpt_print(ccb->ccb_h.path, "%s: [0x%x] cannot find private data adjunct\n", __func__, cso->tag_id);
1414 isp_dump_atpd(isp, tptr);
1415 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1416 xpt_done(ccb);
1417 return;
1418 }
1419 if (atp->dead) {
1420 xpt_print(ccb->ccb_h.path, "%s: [0x%x] stopping sending a CTIO for a dead command\n", __func__, cso->tag_id);
1421 ccb->ccb_h.status = CAM_REQ_ABORTED;
1422 xpt_done(ccb);
1423 return;
1424 }
1425
1426 /*
1427 * Check to make sure we're still in target mode.
1428 */
1429 if ((FCPARAM(isp, XS_CHANNEL(ccb))->role & ISP_ROLE_TARGET) == 0) {
1430 xpt_print(ccb->ccb_h.path, "%s: [0x%x] stopping sending a CTIO because we're no longer in target mode\n", __func__, cso->tag_id);
1431 ccb->ccb_h.status = CAM_PROVIDE_FAIL;
1432 xpt_done(ccb);
1433 return;
1434 }
1435
1436 /*
1437 * Get some resources
1438 */
1439 if (isp_get_pcmd(isp, ccb)) {
1440 rls_lun_statep(isp, tptr);
1441 xpt_print(ccb->ccb_h.path, "out of PCMDs\n");
1442 cam_freeze_devq(ccb->ccb_h.path);
1443 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
1444 ccb->ccb_h.status = CAM_REQUEUE_REQ;
1445 xpt_done(ccb);
1446 return;
1447 }
1448 qe = isp_getrqentry(isp);
1449 if (qe == NULL) {
1450 xpt_print(ccb->ccb_h.path, rqo, __func__);
1451 cam_freeze_devq(ccb->ccb_h.path);
1452 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
1453 ccb->ccb_h.status = CAM_REQUEUE_REQ;
1214 goto out;
1215 }
1216 memset(local, 0, QENTRY_LEN);
1217
1218 /*
1219 * We're either moving data or completing a command here.
1220 */
1454 goto out;
1455 }
1456 memset(local, 0, QENTRY_LEN);
1457
1458 /*
1459 * We're either moving data or completing a command here.
1460 */
1461 if (IS_24XX(isp)) {
1462 ct7_entry_t *cto = (ct7_entry_t *) local;
1221
1463
1222 if (IS_FC(isp)) {
1223 atio_private_data_t *atp;
1464 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
1465 cto->ct_header.rqs_entry_count = 1;
1466 cto->ct_header.rqs_seqno = 1;
1467 cto->ct_nphdl = atp->nphdl;
1468 cto->ct_rxid = atp->tag;
1469 cto->ct_iid_lo = atp->portid;
1470 cto->ct_iid_hi = atp->portid >> 16;
1471 cto->ct_oxid = atp->oxid;
1472 cto->ct_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(ccb));
1473 cto->ct_scsi_status = cso->scsi_status;
1474 cto->ct_timeout = 120;
1475 cto->ct_flags = atp->tattr << CT7_TASK_ATTR_SHIFT;
1476 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1477 cto->ct_flags |= CT7_SENDSTATUS;
1478 }
1479 if (cso->dxfer_len == 0) {
1480 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_NO_DATA;
1481 if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) {
1482 int m = min(cso->sense_len, sizeof (struct scsi_sense_data));
1483 cto->rsp.m1.ct_resplen = cto->ct_senselen = min(m, MAXRESPLEN_24XX);
1484 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, cto->ct_senselen);
1485 cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8);
1486 }
1487 } else {
1488 cto->ct_flags |= CT7_FLAG_MODE0;
1489 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1490 cto->ct_flags |= CT7_DATA_IN;
1491 } else {
1492 cto->ct_flags |= CT7_DATA_OUT;
1493 }
1494 cto->rsp.m0.reloff = atp->bytes_xfered;
1495 /*
1496 * Don't overrun the limits placed on us
1497 */
1498 if (atp->bytes_xfered + cso->dxfer_len > atp->orig_datalen) {
1499 cso->dxfer_len = atp->orig_datalen - atp->bytes_xfered;
1500 }
1501 atp->last_xframt = cso->dxfer_len;
1502 cto->rsp.m0.ct_xfrlen = cso->dxfer_len;
1503 }
1504 if (cto->ct_flags & CT7_SENDSTATUS) {
1505 int lvl = (cso->scsi_status)? ISP_LOGTINFO : ISP_LOGTDEBUG0;
1506 cto->ct_resid = atp->orig_datalen - (atp->bytes_xfered + cso->dxfer_len);
1507 if (cto->ct_resid < 0) {
1508 cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8);
1509 } else if (cto->ct_resid > 0) {
1510 cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8);
1511 }
1512 atp->state = ATPD_STATE_LAST_CTIO;
1513 ISP_PATH_PRT(isp, lvl, cso->ccb_h.path, "%s: CTIO7[%x] CDB0=%x scsi status %x flags %x resid %d xfrlen %u offset %u\n", __func__, cto->ct_rxid,
1514 atp->cdb0, cto->ct_scsi_status, cto->ct_flags, cto->ct_resid, cso->dxfer_len, atp->bytes_xfered);
1515 } else {
1516 cto->ct_resid = 0;
1517 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, cso->ccb_h.path, "%s: CTIO7[%x] flags %x xfrlen %u offset %u\n", __func__, cto->ct_rxid, cto->ct_flags,
1518 cso->dxfer_len, atp->bytes_xfered);
1519 atp->state = ATPD_STATE_CTIO;
1520 }
1521 } else if (IS_FC(isp)) {
1224 ct2_entry_t *cto = (ct2_entry_t *) local;
1225
1226 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
1227 cto->ct_header.rqs_entry_count = 1;
1522 ct2_entry_t *cto = (ct2_entry_t *) local;
1523
1524 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
1525 cto->ct_header.rqs_entry_count = 1;
1228 if (FCPARAM(isp)->isp_2klogin) {
1526 cto->ct_header.rqs_seqno = 1;
1527 if (ISP_CAP_2KLOGIN(isp) == 0) {
1229 ((ct2e_entry_t *)cto)->ct_iid = cso->init_id;
1230 } else {
1231 cto->ct_iid = cso->init_id;
1528 ((ct2e_entry_t *)cto)->ct_iid = cso->init_id;
1529 } else {
1530 cto->ct_iid = cso->init_id;
1232 if (FCPARAM(isp)->isp_sccfw == 0) {
1531 if (ISP_CAP_SCCFW(isp) == 0) {
1233 cto->ct_lun = ccb->ccb_h.target_lun;
1234 }
1235 }
1236
1532 cto->ct_lun = ccb->ccb_h.target_lun;
1533 }
1534 }
1535
1237 atp = isp_get_atpd(isp, cso->tag_id);
1238 if (atp == NULL) {
1239 xpt_print(ccb->ccb_h.path,
1240 "cannot find private data adjunct for tag %x\n",
1241 cso->tag_id);
1242 XS_SETERR(ccb, CAM_REQ_CMP_ERR);
1243 goto out;
1244 }
1245
1246 cto->ct_rxid = cso->tag_id;
1247 if (cso->dxfer_len == 0) {
1536
1537 cto->ct_rxid = cso->tag_id;
1538 if (cso->dxfer_len == 0) {
1248 cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA;
1249 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1250 cto->ct_flags |= CT2_SENDSTATUS;
1251 cto->rsp.m1.ct_scsi_status = cso->scsi_status;
1252 cto->ct_resid =
1253 atp->orig_datalen - atp->bytes_xfered;
1254 if (cto->ct_resid < 0) {
1255 cto->rsp.m1.ct_scsi_status |=
1256 CT2_DATA_OVER;
1257 } else if (cto->ct_resid > 0) {
1258 cto->rsp.m1.ct_scsi_status |=
1259 CT2_DATA_UNDER;
1260 }
1539 cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA | CT2_SENDSTATUS;
1540 cto->rsp.m1.ct_scsi_status = cso->scsi_status;
1541 cto->ct_resid = atp->orig_datalen - atp->bytes_xfered;
1542 if (cto->ct_resid < 0) {
1543 cto->rsp.m1.ct_scsi_status |= CT2_DATA_OVER;
1544 } else if (cto->ct_resid > 0) {
1545 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
1261 }
1262 if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) {
1263 int m = min(cso->sense_len, MAXRESPLEN);
1546 }
1547 if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) {
1548 int m = min(cso->sense_len, MAXRESPLEN);
1264 memcpy(cto->rsp.m1.ct_resp,
1265 &cso->sense_data, m);
1549 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, m);
1266 cto->rsp.m1.ct_senselen = m;
1267 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
1550 cto->rsp.m1.ct_senselen = m;
1551 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
1552 } else if (cso->scsi_status == SCSI_STATUS_CHECK_COND) {
1553 /*
1554 * XXX: DEBUG
1555 */
1556 xpt_print(ccb->ccb_h.path, "CHECK CONDITION being sent without associated SENSE DATA for CDB=0x%x\n", atp->cdb0);
1268 }
1269 } else {
1270 cto->ct_flags |= CT2_FLAG_MODE0;
1271 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1272 cto->ct_flags |= CT2_DATA_IN;
1273 } else {
1274 cto->ct_flags |= CT2_DATA_OUT;
1275 }
1276 cto->ct_reloff = atp->bytes_xfered;
1557 }
1558 } else {
1559 cto->ct_flags |= CT2_FLAG_MODE0;
1560 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1561 cto->ct_flags |= CT2_DATA_IN;
1562 } else {
1563 cto->ct_flags |= CT2_DATA_OUT;
1564 }
1565 cto->ct_reloff = atp->bytes_xfered;
1566 cto->rsp.m0.ct_xfrlen = cso->dxfer_len;
1567 /*
1568 * Don't overrun the limits placed on us
1569 */
1570 if (atp->bytes_xfered + cso->dxfer_len > atp->orig_datalen) {
1571 cso->dxfer_len = atp->orig_datalen - atp->bytes_xfered;
1572 }
1277 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
1278 cto->ct_flags |= CT2_SENDSTATUS;
1279 cto->rsp.m0.ct_scsi_status = cso->scsi_status;
1573 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
1574 cto->ct_flags |= CT2_SENDSTATUS;
1575 cto->rsp.m0.ct_scsi_status = cso->scsi_status;
1280 cto->ct_resid =
1281 atp->orig_datalen -
1282 (atp->bytes_xfered + cso->dxfer_len);
1576 cto->ct_resid = atp->orig_datalen - (atp->bytes_xfered + cso->dxfer_len);
1283 if (cto->ct_resid < 0) {
1577 if (cto->ct_resid < 0) {
1284 cto->rsp.m0.ct_scsi_status |=
1285 CT2_DATA_OVER;
1578 cto->rsp.m0.ct_scsi_status |= CT2_DATA_OVER;
1286 } else if (cto->ct_resid > 0) {
1579 } else if (cto->ct_resid > 0) {
1287 cto->rsp.m0.ct_scsi_status |=
1288 CT2_DATA_UNDER;
1580 cto->rsp.m0.ct_scsi_status |= CT2_DATA_UNDER;
1289 }
1290 } else {
1291 atp->last_xframt = cso->dxfer_len;
1292 }
1293 /*
1294 * If we're sending data and status back together,
1295 * we can't also send back sense data as well.
1296 */
1297 ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1298 }
1299
1300 if (cto->ct_flags & CT2_SENDSTATUS) {
1581 }
1582 } else {
1583 atp->last_xframt = cso->dxfer_len;
1584 }
1585 /*
1586 * If we're sending data and status back together,
1587 * we can't also send back sense data as well.
1588 */
1589 ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1590 }
1591
1592 if (cto->ct_flags & CT2_SENDSTATUS) {
1301 isp_prt(isp, ISP_LOGTDEBUG0,
1302 "CTIO2[%x] STATUS %x origd %u curd %u resid %u",
1303 cto->ct_rxid, cso->scsi_status, atp->orig_datalen,
1304 cso->dxfer_len, cto->ct_resid);
1593 int lvl = (cso->scsi_status)? ISP_LOGTINFO : ISP_LOGTDEBUG0;
1305 cto->ct_flags |= CT2_CCINCR;
1306 atp->state = ATPD_STATE_LAST_CTIO;
1594 cto->ct_flags |= CT2_CCINCR;
1595 atp->state = ATPD_STATE_LAST_CTIO;
1596 ISP_PATH_PRT(isp, lvl, cso->ccb_h.path, "%s: CTIO2[%x] CDB0=%x scsi status %x flags %x resid %d xfrlen %u offset %u\n", __func__, cto->ct_rxid,
1597 atp->cdb0, cto->rsp.m0.ct_scsi_status, cto->ct_flags, cto->ct_resid, cso->dxfer_len, atp->bytes_xfered);
1307 } else {
1598 } else {
1599 cto->ct_resid = 0;
1308 atp->state = ATPD_STATE_CTIO;
1600 atp->state = ATPD_STATE_CTIO;
1601 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: CTIO2[%x] flags %x xfrlen %u offset %u\n", __func__, cto->ct_rxid, cto->ct_flags,
1602 cso->dxfer_len, atp->bytes_xfered);
1309 }
1310 cto->ct_timeout = 10;
1311 } else {
1312 ct_entry_t *cto = (ct_entry_t *) local;
1313
1314 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
1315 cto->ct_header.rqs_entry_count = 1;
1603 }
1604 cto->ct_timeout = 10;
1605 } else {
1606 ct_entry_t *cto = (ct_entry_t *) local;
1607
1608 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
1609 cto->ct_header.rqs_entry_count = 1;
1610 cto->ct_header.rqs_seqno = 1;
1316 cto->ct_iid = cso->init_id;
1317 cto->ct_iid |= XS_CHANNEL(ccb) << 7;
1318 cto->ct_tgt = ccb->ccb_h.target_id;
1319 cto->ct_lun = ccb->ccb_h.target_lun;
1611 cto->ct_iid = cso->init_id;
1612 cto->ct_iid |= XS_CHANNEL(ccb) << 7;
1613 cto->ct_tgt = ccb->ccb_h.target_id;
1614 cto->ct_lun = ccb->ccb_h.target_lun;
1320 cto->ct_fwhandle = AT_GET_HANDLE(cso->tag_id);
1615 cto->ct_fwhandle = cso->tag_id >> 16;
1321 if (AT_HAS_TAG(cso->tag_id)) {
1616 if (AT_HAS_TAG(cso->tag_id)) {
1322 cto->ct_tag_val = (uint8_t) AT_GET_TAG(cso->tag_id);
1617 cto->ct_tag_val = cso->tag_id;
1323 cto->ct_flags |= CT_TQAE;
1324 }
1325 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) {
1326 cto->ct_flags |= CT_NODISC;
1327 }
1328 if (cso->dxfer_len == 0) {
1329 cto->ct_flags |= CT_NO_DATA;
1330 } else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1331 cto->ct_flags |= CT_DATA_IN;
1332 } else {
1333 cto->ct_flags |= CT_DATA_OUT;
1334 }
1335 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1336 cto->ct_flags |= CT_SENDSTATUS|CT_CCINCR;
1337 cto->ct_scsi_status = cso->scsi_status;
1338 cto->ct_resid = cso->resid;
1618 cto->ct_flags |= CT_TQAE;
1619 }
1620 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) {
1621 cto->ct_flags |= CT_NODISC;
1622 }
1623 if (cso->dxfer_len == 0) {
1624 cto->ct_flags |= CT_NO_DATA;
1625 } else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1626 cto->ct_flags |= CT_DATA_IN;
1627 } else {
1628 cto->ct_flags |= CT_DATA_OUT;
1629 }
1630 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1631 cto->ct_flags |= CT_SENDSTATUS|CT_CCINCR;
1632 cto->ct_scsi_status = cso->scsi_status;
1633 cto->ct_resid = cso->resid;
1339 isp_prt(isp, ISP_LOGTDEBUG0,
1340 "CTIO[%x] SCSI STATUS 0x%x resid %d tag_id %x",
1341 cto->ct_fwhandle, cso->scsi_status, cso->resid,
1342 cso->tag_id);
1634 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: CTIO[%x] scsi status %x resid %d tag_id %x\n", __func__,
1635 cto->ct_fwhandle, cso->scsi_status, cso->resid, cso->tag_id);
1343 }
1344 ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1345 cto->ct_timeout = 10;
1346 }
1347
1348 if (isp_save_xs_tgt(isp, ccb, &handle)) {
1636 }
1637 ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1638 cto->ct_timeout = 10;
1639 }
1640
1641 if (isp_save_xs_tgt(isp, ccb, &handle)) {
1349 xpt_print(ccb->ccb_h.path,
1350 "No XFLIST pointers for isp_target_start_ctio\n");
1351 XS_SETERR(ccb, CAM_REQUEUE_REQ);
1642 xpt_print(ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__);
1643 ccb->ccb_h.status = CAM_REQUEUE_REQ;
1352 goto out;
1353 }
1354
1355
1356 /*
1357 * Call the dma setup routines for this entry (and any subsequent
1358 * CTIOs) if there's data to move, and then tell the f/w it's got
1359 * new things to play with. As with isp_start's usage of DMA setup,
1360 * any swizzling is done in the machine dependent layer. Because
1361 * of this, we put the request onto the queue area first in native
1362 * format.
1363 */
1364
1644 goto out;
1645 }
1646
1647
1648 /*
1649 * Call the dma setup routines for this entry (and any subsequent
1650 * CTIOs) if there's data to move, and then tell the f/w it's got
1651 * new things to play with. As with isp_start's usage of DMA setup,
1652 * any swizzling is done in the machine dependent layer. Because
1653 * of this, we put the request onto the queue area first in native
1654 * format.
1655 */
1656
1365 if (IS_FC(isp)) {
1657 if (IS_24XX(isp)) {
1658 ct7_entry_t *cto = (ct7_entry_t *) local;
1659 cto->ct_syshandle = handle;
1660 } else if (IS_FC(isp)) {
1366 ct2_entry_t *cto = (ct2_entry_t *) local;
1367 cto->ct_syshandle = handle;
1368 } else {
1369 ct_entry_t *cto = (ct_entry_t *) local;
1370 cto->ct_syshandle = handle;
1371 }
1372
1661 ct2_entry_t *cto = (ct2_entry_t *) local;
1662 cto->ct_syshandle = handle;
1663 } else {
1664 ct_entry_t *cto = (ct_entry_t *) local;
1665 cto->ct_syshandle = handle;
1666 }
1667
1373 switch (ISP_DMASETUP(isp, cso, (ispreq_t *) local, &nxti, optr)) {
1374 case CMD_QUEUED:
1375 ISP_ADD_REQUEST(isp, nxti);
1668 dmaresult = ISP_DMASETUP(isp, cso, (ispreq_t *) local);
1669 if (dmaresult == CMD_QUEUED) {
1670 isp->isp_nactive++;
1376 ccb->ccb_h.status |= CAM_SIM_QUEUED;
1671 ccb->ccb_h.status |= CAM_SIM_QUEUED;
1672 rls_lun_statep(isp, tptr);
1377 return;
1673 return;
1378
1379 case CMD_EAGAIN:
1380 XS_SETERR(ccb, CAM_REQUEUE_REQ);
1381 break;
1382
1383 default:
1384 break;
1385 }
1674 }
1675 if (dmaresult == CMD_EAGAIN) {
1676 ccb->ccb_h.status = CAM_REQUEUE_REQ;
1677 } else {
1678 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1679 }
1386 isp_destroy_tgt_handle(isp, handle);
1680 isp_destroy_tgt_handle(isp, handle);
1387
1388out:
1681out:
1682 rls_lun_statep(isp, tptr);
1683 isp_free_pcmd(isp, ccb);
1389 xpt_done(ccb);
1390}
1391
1392static void
1393isp_refire_putback_atio(void *arg)
1394{
1684 xpt_done(ccb);
1685}
1686
1687static void
1688isp_refire_putback_atio(void *arg)
1689{
1395 int s = splcam();
1396 isp_target_putback_atio(arg);
1397 splx(s);
1690 union ccb *ccb = arg;
1691 ispsoftc_t *isp = XS_ISP(ccb);
1692 ISP_LOCK(isp);
1693 isp_target_putback_atio(ccb);
1694 ISP_UNLOCK(isp);
1398}
1399
1400static void
1401isp_target_putback_atio(union ccb *ccb)
1402{
1403 ispsoftc_t *isp;
1404 struct ccb_scsiio *cso;
1695}
1696
1697static void
1698isp_target_putback_atio(union ccb *ccb)
1699{
1700 ispsoftc_t *isp;
1701 struct ccb_scsiio *cso;
1405 uint32_t nxti, optr;
1406 void *qe;
1407
1408 isp = XS_ISP(ccb);
1409
1702 void *qe;
1703
1704 isp = XS_ISP(ccb);
1705
1410 if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
1411 xpt_print(ccb->ccb_h.path,
1412 "isp_target_putback_atio: Request Queue Overflow\n");
1706 qe = isp_getrqentry(isp);
1707 if (qe == NULL) {
1708 xpt_print(ccb->ccb_h.path, rqo, __func__);
1413 (void) timeout(isp_refire_putback_atio, ccb, 10);
1414 return;
1415 }
1416 memset(qe, 0, QENTRY_LEN);
1417 cso = &ccb->csio;
1418 if (IS_FC(isp)) {
1419 at2_entry_t local, *at = &local;
1709 (void) timeout(isp_refire_putback_atio, ccb, 10);
1710 return;
1711 }
1712 memset(qe, 0, QENTRY_LEN);
1713 cso = &ccb->csio;
1714 if (IS_FC(isp)) {
1715 at2_entry_t local, *at = &local;
1420 MEMZERO(at, sizeof (at2_entry_t));
1716 ISP_MEMZERO(at, sizeof (at2_entry_t));
1421 at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
1422 at->at_header.rqs_entry_count = 1;
1717 at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
1718 at->at_header.rqs_entry_count = 1;
1423 if (FCPARAM(isp)->isp_sccfw) {
1719 if (ISP_CAP_SCCFW(isp)) {
1424 at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
1425 } else {
1426 at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
1427 }
1428 at->at_status = CT_OK;
1429 at->at_rxid = cso->tag_id;
1430 at->at_iid = cso->ccb_h.target_id;
1431 isp_put_atio2(isp, at, qe);
1432 } else {
1433 at_entry_t local, *at = &local;
1720 at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
1721 } else {
1722 at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
1723 }
1724 at->at_status = CT_OK;
1725 at->at_rxid = cso->tag_id;
1726 at->at_iid = cso->ccb_h.target_id;
1727 isp_put_atio2(isp, at, qe);
1728 } else {
1729 at_entry_t local, *at = &local;
1434 MEMZERO(at, sizeof (at_entry_t));
1730 ISP_MEMZERO(at, sizeof (at_entry_t));
1435 at->at_header.rqs_entry_type = RQSTYPE_ATIO;
1436 at->at_header.rqs_entry_count = 1;
1437 at->at_iid = cso->init_id;
1438 at->at_iid |= XS_CHANNEL(ccb) << 7;
1439 at->at_tgt = cso->ccb_h.target_id;
1440 at->at_lun = cso->ccb_h.target_lun;
1441 at->at_status = CT_OK;
1442 at->at_tag_val = AT_GET_TAG(cso->tag_id);
1443 at->at_handle = AT_GET_HANDLE(cso->tag_id);
1444 isp_put_atio(isp, at, qe);
1445 }
1731 at->at_header.rqs_entry_type = RQSTYPE_ATIO;
1732 at->at_header.rqs_entry_count = 1;
1733 at->at_iid = cso->init_id;
1734 at->at_iid |= XS_CHANNEL(ccb) << 7;
1735 at->at_tgt = cso->ccb_h.target_id;
1736 at->at_lun = cso->ccb_h.target_lun;
1737 at->at_status = CT_OK;
1738 at->at_tag_val = AT_GET_TAG(cso->tag_id);
1739 at->at_handle = AT_GET_HANDLE(cso->tag_id);
1740 isp_put_atio(isp, at, qe);
1741 }
1446 ISP_TDQE(isp, "isp_target_putback_atio", (int) optr, qe);
1447 ISP_ADD_REQUEST(isp, nxti);
1742 ISP_TDQE(isp, "isp_target_putback_atio", isp->isp_reqidx, qe);
1743 ISP_SYNC_REQUEST(isp);
1448 isp_complete_ctio(ccb);
1449}
1450
1451static void
1452isp_complete_ctio(union ccb *ccb)
1453{
1454 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
1455 ccb->ccb_h.status |= CAM_REQ_CMP;
1456 }
1457 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1744 isp_complete_ctio(ccb);
1745}
1746
1747static void
1748isp_complete_ctio(union ccb *ccb)
1749{
1750 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
1751 ccb->ccb_h.status |= CAM_REQ_CMP;
1752 }
1753 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1754 isp_free_pcmd(XS_ISP(ccb), ccb);
1458 xpt_done(ccb);
1459}
1460
1461/*
1462 * Handle ATIO stuff that the generic code can't.
1463 * This means handling CDBs.
1464 */
1465
1755 xpt_done(ccb);
1756}
1757
1758/*
1759 * Handle ATIO stuff that the generic code can't.
1760 * This means handling CDBs.
1761 */
1762
1466static int
1763static void
1467isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep)
1468{
1469 tstate_t *tptr;
1764isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep)
1765{
1766 tstate_t *tptr;
1470 int status, bus, iswildcard;
1767 int status, bus;
1471 struct ccb_accept_tio *atiop;
1768 struct ccb_accept_tio *atiop;
1769 atio_private_data_t *atp;
1472
1473 /*
1474 * The firmware status (except for the QLTM_SVALID bit)
1475 * indicates why this ATIO was sent to us.
1476 *
1477 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1478 *
1479 * If the DISCONNECTS DISABLED bit is set in the flags field,
1480 * we're still connected on the SCSI bus.
1481 */
1482 status = aep->at_status;
1483 if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
1484 /*
1485 * Bus Phase Sequence error. We should have sense data
1486 * suggested by the f/w. I'm not sure quite yet what
1487 * to do about this for CAM.
1488 */
1489 isp_prt(isp, ISP_LOGWARN, "PHASE ERROR");
1490 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1770
1771 /*
1772 * The firmware status (except for the QLTM_SVALID bit)
1773 * indicates why this ATIO was sent to us.
1774 *
1775 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1776 *
1777 * If the DISCONNECTS DISABLED bit is set in the flags field,
1778 * we're still connected on the SCSI bus.
1779 */
1780 status = aep->at_status;
1781 if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
1782 /*
1783 * Bus Phase Sequence error. We should have sense data
1784 * suggested by the f/w. I'm not sure quite yet what
1785 * to do about this for CAM.
1786 */
1787 isp_prt(isp, ISP_LOGWARN, "PHASE ERROR");
1788 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1491 return (0);
1789 return;
1492 }
1493 if ((status & ~QLTM_SVALID) != AT_CDB) {
1790 }
1791 if ((status & ~QLTM_SVALID) != AT_CDB) {
1494 isp_prt(isp, ISP_LOGWARN, "bad atio (0x%x) leaked to platform",
1495 status);
1792 isp_prt(isp, ISP_LOGWARN, "bad atio (0x%x) leaked to platform", status);
1496 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1793 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1497 return (0);
1794 return;
1498 }
1499
1500 bus = GET_BUS_VAL(aep->at_iid);
1501 tptr = get_lun_statep(isp, bus, aep->at_lun);
1502 if (tptr == NULL) {
1503 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
1504 if (tptr == NULL) {
1505 /*
1506 * Because we can't autofeed sense data back with
1507 * a command for parallel SCSI, we can't give back
1508 * a CHECK CONDITION. We'll give back a BUSY status
1509 * instead. This works out okay because the only
1510 * time we should, in fact, get this, is in the
1511 * case that somebody configured us without the
1512 * blackhole driver, so they get what they deserve.
1513 */
1514 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1795 }
1796
1797 bus = GET_BUS_VAL(aep->at_iid);
1798 tptr = get_lun_statep(isp, bus, aep->at_lun);
1799 if (tptr == NULL) {
1800 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
1801 if (tptr == NULL) {
1802 /*
1803 * Because we can't autofeed sense data back with
1804 * a command for parallel SCSI, we can't give back
1805 * a CHECK CONDITION. We'll give back a BUSY status
1806 * instead. This works out okay because the only
1807 * time we should, in fact, get this, is in the
1808 * case that somebody configured us without the
1809 * blackhole driver, so they get what they deserve.
1810 */
1811 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1515 return (0);
1812 return;
1516 }
1813 }
1517 iswildcard = 1;
1518 } else {
1519 iswildcard = 0;
1520 }
1521
1814 }
1815
1816 atp = isp_get_atpd(isp, tptr, 0);
1522 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1817 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1523 if (atiop == NULL) {
1818 if (atiop == NULL || atp == NULL) {
1524 /*
1525 * Because we can't autofeed sense data back with
1526 * a command for parallel SCSI, we can't give back
1527 * a CHECK CONDITION. We'll give back a QUEUE FULL status
1528 * instead. This works out okay because the only time we
1529 * should, in fact, get this, is in the case that we've
1530 * run out of ATIOS.
1531 */
1819 /*
1820 * Because we can't autofeed sense data back with
1821 * a command for parallel SCSI, we can't give back
1822 * a CHECK CONDITION. We'll give back a QUEUE FULL status
1823 * instead. This works out okay because the only time we
1824 * should, in fact, get this, is in the case that we've
1825 * run out of ATIOS.
1826 */
1532 xpt_print(tptr->owner,
1533 "no ATIOS for lun %d from initiator %d on channel %d\n",
1534 aep->at_lun, GET_IID_VAL(aep->at_iid), bus);
1535 if (aep->at_flags & AT_TQAE)
1536 isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1537 else
1538 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1827 xpt_print(tptr->owner, "no %s for lun %d from initiator %d\n", (atp == NULL && atiop == NULL)? "ATIOs *or* ATPS" :
1828 ((atp == NULL)? "ATPs" : "ATIOs"), aep->at_lun, aep->at_iid);
1829 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1830 if (atp) {
1831 isp_put_atpd(isp, tptr, atp);
1832 }
1539 rls_lun_statep(isp, tptr);
1833 rls_lun_statep(isp, tptr);
1540 return (0);
1834 return;
1541 }
1835 }
1836 atp->tag = aep->at_tag_val;
1837 if (atp->tag == 0) {
1838 atp->tag = ~0;
1839 }
1840 atp->state = ATPD_STATE_ATIO;
1542 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1543 tptr->atio_count--;
1841 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1842 tptr->atio_count--;
1544 isp_prt(isp, ISP_LOGTDEBUG0, "Take FREE ATIO lun %d, count now %d",
1545 aep->at_lun, tptr->atio_count);
1546 if (iswildcard) {
1547 atiop->ccb_h.target_id = aep->at_tgt;
1548 atiop->ccb_h.target_lun = aep->at_lun;
1549 }
1843 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, atiop->ccb_h.path, "Take FREE ATIO count now %d\n", tptr->atio_count);
1844 atiop->ccb_h.target_id = aep->at_tgt;
1845 atiop->ccb_h.target_lun = aep->at_lun;
1550 if (aep->at_flags & AT_NODISC) {
1551 atiop->ccb_h.flags = CAM_DIS_DISCONNECT;
1552 } else {
1553 atiop->ccb_h.flags = 0;
1554 }
1555
1556 if (status & QLTM_SVALID) {
1557 size_t amt = imin(QLTM_SENSELEN, sizeof (atiop->sense_data));
1558 atiop->sense_len = amt;
1846 if (aep->at_flags & AT_NODISC) {
1847 atiop->ccb_h.flags = CAM_DIS_DISCONNECT;
1848 } else {
1849 atiop->ccb_h.flags = 0;
1850 }
1851
1852 if (status & QLTM_SVALID) {
1853 size_t amt = imin(QLTM_SENSELEN, sizeof (atiop->sense_data));
1854 atiop->sense_len = amt;
1559 MEMCPY(&atiop->sense_data, aep->at_sense, amt);
1855 ISP_MEMCPY(&atiop->sense_data, aep->at_sense, amt);
1560 } else {
1561 atiop->sense_len = 0;
1562 }
1563
1564 atiop->init_id = GET_IID_VAL(aep->at_iid);
1565 atiop->cdb_len = aep->at_cdblen;
1856 } else {
1857 atiop->sense_len = 0;
1858 }
1859
1860 atiop->init_id = GET_IID_VAL(aep->at_iid);
1861 atiop->cdb_len = aep->at_cdblen;
1566 MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
1862 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
1567 atiop->ccb_h.status = CAM_CDB_RECVD;
1568 /*
1569 * Construct a tag 'id' based upon tag value (which may be 0..255)
1570 * and the handle (which we have to preserve).
1571 */
1863 atiop->ccb_h.status = CAM_CDB_RECVD;
1864 /*
1865 * Construct a tag 'id' based upon tag value (which may be 0..255)
1866 * and the handle (which we have to preserve).
1867 */
1572 AT_MAKE_TAGID(atiop->tag_id, bus, device_get_unit(isp->isp_dev), aep);
1868 atiop->tag_id = atp->tag;
1573 if (aep->at_flags & AT_TQAE) {
1574 atiop->tag_action = aep->at_tag_type;
1575 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
1576 }
1869 if (aep->at_flags & AT_TQAE) {
1870 atiop->tag_action = aep->at_tag_type;
1871 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
1872 }
1577 xpt_done((union ccb*)atiop);
1578 isp_prt(isp, ISP_LOGTDEBUG0,
1579 "ATIO[%x] CDB=0x%x bus %d iid%d->lun%d tag 0x%x ttype 0x%x %s",
1580 aep->at_handle, aep->at_cdb[0] & 0xff, GET_BUS_VAL(aep->at_iid),
1581 GET_IID_VAL(aep->at_iid), aep->at_lun, aep->at_tag_val & 0xff,
1582 aep->at_tag_type, (aep->at_flags & AT_NODISC)?
1583 "nondisc" : "disconnecting");
1873 atp->orig_datalen = 0;
1874 atp->bytes_xfered = 0;
1875 atp->last_xframt = 0;
1876 atp->lun = aep->at_lun;
1877 atp->nphdl = aep->at_iid;
1878 atp->portid = PORT_NONE;
1879 atp->oxid = 0;
1880 atp->cdb0 = atiop->cdb_io.cdb_bytes[0];
1881 atp->tattr = aep->at_tag_type;
1882 atp->state = ATPD_STATE_CAM;
1883 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "ATIO[%x] CDB=0x%x lun %d\n", aep->at_tag_val, atp->cdb0, atp->lun);
1584 rls_lun_statep(isp, tptr);
1884 rls_lun_statep(isp, tptr);
1585 return (0);
1586}
1587
1885}
1886
1588static int
1887static void
1589isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1590{
1591 lun_id_t lun;
1888isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1889{
1890 lun_id_t lun;
1891 fcportdb_t *lp;
1592 tstate_t *tptr;
1593 struct ccb_accept_tio *atiop;
1892 tstate_t *tptr;
1893 struct ccb_accept_tio *atiop;
1594 atio_private_data_t *atp;
1894 uint16_t nphdl;
1895 atio_private_data_t *atp = NULL;
1896 inot_private_data_t *ntp;
1595
1596 /*
1597 * The firmware status (except for the QLTM_SVALID bit)
1598 * indicates why this ATIO was sent to us.
1599 *
1600 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1601 */
1602 if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
1897
1898 /*
1899 * The firmware status (except for the QLTM_SVALID bit)
1900 * indicates why this ATIO was sent to us.
1901 *
1902 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1903 */
1904 if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
1603 isp_prt(isp, ISP_LOGWARN,
1604 "bogus atio (0x%x) leaked to platform", aep->at_status);
1905 isp_prt(isp, ISP_LOGWARN, "bogus atio (0x%x) leaked to platform", aep->at_status);
1605 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1906 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1606 return (0);
1907 return;
1607 }
1608
1908 }
1909
1609 if (FCPARAM(isp)->isp_sccfw) {
1910 if (ISP_CAP_SCCFW(isp)) {
1610 lun = aep->at_scclun;
1611 } else {
1612 lun = aep->at_lun;
1613 }
1911 lun = aep->at_scclun;
1912 } else {
1913 lun = aep->at_lun;
1914 }
1915 if (ISP_CAP_2KLOGIN(isp)) {
1916 nphdl = ((at2e_entry_t *)aep)->at_iid;
1917 } else {
1918 nphdl = aep->at_iid;
1919 }
1614 tptr = get_lun_statep(isp, 0, lun);
1615 if (tptr == NULL) {
1920 tptr = get_lun_statep(isp, 0, lun);
1921 if (tptr == NULL) {
1616 isp_prt(isp, ISP_LOGTDEBUG0,
1617 "[0x%x] no state pointer for lun %d", aep->at_rxid, lun);
1618 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
1619 if (tptr == NULL) {
1922 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
1923 if (tptr == NULL) {
1620 isp_endcmd(isp, aep,
1621 SCSI_STATUS_CHECK_COND | ECMD_SVALID |
1622 (0x5 << 12) | (0x25 << 16), 0);
1623 return (0);
1924 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] no state pointer for lun %d", aep->at_rxid, lun);
1925 isp_endcmd(isp, aep, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
1926 return;
1624 }
1625 }
1626
1927 }
1928 }
1929
1627 atp = isp_get_atpd(isp, 0);
1930 /*
1931 * Start any commands pending resources first.
1932 */
1933 if (tptr->restart_queue) {
1934 inot_private_data_t *restart_queue = tptr->restart_queue;
1935 tptr->restart_queue = NULL;
1936 while (restart_queue) {
1937 ntp = restart_queue;
1938 restart_queue = ntp->rd.nt.nt_hba;
1939 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid);
1940 isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data);
1941 isp_put_ntpd(isp, tptr, ntp);
1942 /*
1943 * If a recursion caused the restart queue to start to fill again,
1944 * stop and splice the new list on top of the old list and restore
1945 * it and go to noresrc.
1946 */
1947 if (tptr->restart_queue) {
1948 ntp = tptr->restart_queue;
1949 tptr->restart_queue = restart_queue;
1950 while (restart_queue->rd.nt.nt_hba) {
1951 restart_queue = restart_queue->rd.nt.nt_hba;
1952 }
1953 restart_queue->rd.nt.nt_hba = ntp;
1954 goto noresrc;
1955 }
1956 }
1957 }
1958
1628 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1959 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1629 if (atiop == NULL || atp == NULL) {
1960 if (atiop == NULL) {
1961 goto noresrc;
1962 }
1630
1963
1631 /*
1632 * Because we can't autofeed sense data back with
1633 * a command for parallel SCSI, we can't give back
1634 * a CHECK CONDITION. We'll give back a QUEUE FULL status
1635 * instead. This works out okay because the only time we
1636 * should, in fact, get this, is in the case that we've
1637 * run out of ATIOS.
1638 */
1639 xpt_print(tptr->owner,
1640 "no %s for lun %d from initiator %d\n",
1641 (atp == NULL && atiop == NULL)? "ATIO2s *or* ATPS" :
1642 ((atp == NULL)? "ATPs" : "ATIO2s"), lun, aep->at_iid);
1643 rls_lun_statep(isp, tptr);
1644 isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1645 return (0);
1964 atp = isp_get_atpd(isp, tptr, 0);
1965 if (atp == NULL) {
1966 goto noresrc;
1646 }
1967 }
1968
1969 atp->tag = aep->at_rxid;
1647 atp->state = ATPD_STATE_ATIO;
1648 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1649 tptr->atio_count--;
1970 atp->state = ATPD_STATE_ATIO;
1971 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1972 tptr->atio_count--;
1650 isp_prt(isp, ISP_LOGTDEBUG0, "Take FREE ATIO lun %d, count now %d",
1651 lun, tptr->atio_count);
1973 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, atiop->ccb_h.path, "Take FREE ATIO count now %d\n", tptr->atio_count);
1974 atiop->ccb_h.target_id = FCPARAM(isp, 0)->isp_loopid;
1975 atiop->ccb_h.target_lun = lun;
1652
1976
1653 if (tptr == &isp->isp_osinfo.tsdflt[0]) {
1654 atiop->ccb_h.target_id = FCPARAM(isp)->isp_loopid;
1655 atiop->ccb_h.target_lun = lun;
1656 }
1657 /*
1658 * We don't get 'suggested' sense data as we do with SCSI cards.
1659 */
1660 atiop->sense_len = 0;
1977 /*
1978 * We don't get 'suggested' sense data as we do with SCSI cards.
1979 */
1980 atiop->sense_len = 0;
1981 if (ISP_CAP_2KLOGIN(isp)) {
1982 /*
1983 * NB: We could not possibly have 2K logins if we
1984 * NB: also did not have SCC FW.
1985 */
1986 atiop->init_id = ((at2e_entry_t *)aep)->at_iid;
1987 } else {
1988 atiop->init_id = aep->at_iid;
1989 }
1661
1990
1662 atiop->init_id = aep->at_iid;
1991 /*
1992 * If we're not in the port database, add ourselves.
1993 */
1994 if (!IS_2100(isp) && isp_find_pdb_by_loopid(isp, 0, atiop->init_id, &lp) == 0) {
1995 uint64_t iid =
1996 (((uint64_t) aep->at_wwpn[0]) << 48) |
1997 (((uint64_t) aep->at_wwpn[1]) << 32) |
1998 (((uint64_t) aep->at_wwpn[2]) << 16) |
1999 (((uint64_t) aep->at_wwpn[3]) << 0);
2000 /*
2001 * However, make sure we delete ourselves if otherwise
2002 * we were there but at a different loop id.
2003 */
2004 if (isp_find_pdb_by_wwn(isp, 0, iid, &lp)) {
2005 isp_del_wwn_entry(isp, 0, iid, lp->handle, lp->portid);
2006 }
2007 isp_add_wwn_entry(isp, 0, iid, atiop->init_id, PORT_ANY);
2008 }
1663 atiop->cdb_len = ATIO2_CDBLEN;
2009 atiop->cdb_len = ATIO2_CDBLEN;
1664 MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
2010 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
1665 atiop->ccb_h.status = CAM_CDB_RECVD;
2011 atiop->ccb_h.status = CAM_CDB_RECVD;
1666 atiop->tag_id = aep->at_rxid;
2012 atiop->tag_id = atp->tag;
1667 switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
1668 case ATIO2_TC_ATTR_SIMPLEQ:
2013 switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
2014 case ATIO2_TC_ATTR_SIMPLEQ:
2015 atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
1669 atiop->tag_action = MSG_SIMPLE_Q_TAG;
1670 break;
2016 atiop->tag_action = MSG_SIMPLE_Q_TAG;
2017 break;
1671 case ATIO2_TC_ATTR_HEADOFQ:
2018 case ATIO2_TC_ATTR_HEADOFQ:
2019 atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
1672 atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1673 break;
2020 atiop->tag_action = MSG_HEAD_OF_Q_TAG;
2021 break;
1674 case ATIO2_TC_ATTR_ORDERED:
2022 case ATIO2_TC_ATTR_ORDERED:
2023 atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
1675 atiop->tag_action = MSG_ORDERED_Q_TAG;
1676 break;
2024 atiop->tag_action = MSG_ORDERED_Q_TAG;
2025 break;
1677 case ATIO2_TC_ATTR_ACAQ: /* ?? */
2026 case ATIO2_TC_ATTR_ACAQ: /* ?? */
1678 case ATIO2_TC_ATTR_UNTAGGED:
1679 default:
1680 atiop->tag_action = 0;
1681 break;
1682 }
2027 case ATIO2_TC_ATTR_UNTAGGED:
2028 default:
2029 atiop->tag_action = 0;
2030 break;
2031 }
1683 atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
1684
2032
1685 atp->tag = atiop->tag_id;
1686 atp->lun = lun;
1687 atp->orig_datalen = aep->at_datalen;
2033 atp->orig_datalen = aep->at_datalen;
1688 atp->last_xframt = 0;
1689 atp->bytes_xfered = 0;
2034 atp->bytes_xfered = 0;
2035 atp->last_xframt = 0;
2036 atp->lun = lun;
2037 atp->nphdl = atiop->init_id;
2038 atp->sid = PORT_ANY;
2039 atp->oxid = aep->at_oxid;
2040 atp->cdb0 = aep->at_cdb[0];
2041 atp->tattr = aep->at_taskflags & ATIO2_TC_ATTR_MASK;
1690 atp->state = ATPD_STATE_CAM;
2042 atp->state = ATPD_STATE_CAM;
1691 xpt_done((union ccb*)atiop);
2043 xpt_done((union ccb *)atiop);
2044 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "ATIO2[%x] CDB=0x%x lun %d datalen %u\n", aep->at_rxid, atp->cdb0, lun, atp->orig_datalen);
2045 rls_lun_statep(isp, tptr);
2046 return;
2047noresrc:
2048 if (atp) {
2049 isp_put_atpd(isp, tptr, atp);
2050 }
2051 ntp = isp_get_ntpd(isp, tptr);
2052 if (ntp == NULL) {
2053 rls_lun_statep(isp, tptr);
2054 isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
2055 return;
2056 }
2057 memcpy(ntp->rd.data, aep, QENTRY_LEN);
2058 ntp->rd.nt.nt_hba = tptr->restart_queue;
2059 tptr->restart_queue = ntp;
2060 rls_lun_statep(isp, tptr);
2061}
1692
2062
1693 isp_prt(isp, ISP_LOGTDEBUG0,
1694 "ATIO2[%x] CDB=0x%x iid%d->lun%d tattr 0x%x datalen %u",
1695 aep->at_rxid, aep->at_cdb[0] & 0xff, aep->at_iid,
1696 lun, aep->at_taskflags, aep->at_datalen);
2063static void
2064isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
2065{
2066 int cdbxlen;
2067 uint16_t lun, chan, nphdl = NIL_HANDLE;
2068 uint32_t did, sid;
2069 uint64_t wwn = INI_NONE;
2070 fcportdb_t *lp;
2071 tstate_t *tptr;
2072 struct ccb_accept_tio *atiop;
2073 atio_private_data_t *atp = NULL;
2074 inot_private_data_t *ntp;
2075
2076 did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2];
2077 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
2078 lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | aep->at_cmnd.fcp_cmnd_lun[1];
2079
2080 /*
2081 * Find the N-port handle, and Virtual Port Index for this command.
2082 *
2083 * If we can't, we're somewhat in trouble because we can't actually respond w/o that information.
2084 * We also, as a matter of course, need to know the WWN of the initiator too.
2085 */
2086 if (ISP_CAP_MULTI_ID(isp)) {
2087 /*
2088 * Find the right channel based upon D_ID
2089 */
2090 isp_find_chan_by_did(isp, did, &chan);
2091
2092 if (chan == ISP_NOCHAN) {
2093 NANOTIME_T now;
2094
2095 /*
2096 * If we don't recognizer our own D_DID, terminate the exchange, unless we're within 2 seconds of startup
2097 * It's a bit tricky here as we need to stash this command *somewhere*.
2098 */
2099 GET_NANOTIME(&now);
2100 if (NANOTIME_SUB(&isp->isp_init_time, &now) > 2000000000ULL) {
2101 isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- dropping", __func__, aep->at_rxid, did);
2102 isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0);
2103 return;
2104 }
2105 tptr = get_lun_statep(isp, 0, 0);
2106 if (tptr == NULL) {
2107 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
2108 if (tptr == NULL) {
2109 isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel and no tptr- dropping", __func__, aep->at_rxid, did);
2110 isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0);
2111 return;
2112 }
2113 }
2114 isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- deferring", __func__, aep->at_rxid, did);
2115 goto noresrc;
2116 }
2117 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x", __func__, aep->at_rxid, did, chan, sid);
2118 } else {
2119 chan = 0;
2120 }
2121
2122 /*
2123 * Find the PDB entry for this initiator
2124 */
2125 if (isp_find_pdb_by_sid(isp, chan, sid, &lp) == 0) {
2126 /*
2127 * If we're not in the port database terminate the exchange.
2128 */
2129 isp_prt(isp, ISP_LOGTINFO, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x wasn't in PDB already",
2130 __func__, aep->at_rxid, did, chan, sid);
2131 isp_endcmd(isp, aep, NIL_HANDLE, chan, ECMD_TERMINATE, 0);
2132 return;
2133 }
2134 nphdl = lp->handle;
2135 wwn = lp->port_wwn;
2136
2137 /*
2138 * Get the tstate pointer
2139 */
2140 tptr = get_lun_statep(isp, chan, lun);
2141 if (tptr == NULL) {
2142 tptr = get_lun_statep(isp, chan, CAM_LUN_WILDCARD);
2143 if (tptr == NULL) {
2144 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] no state pointer for lun %d or wildcard", aep->at_rxid, lun);
2145 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
2146 return;
2147 }
2148 }
2149
2150 /*
2151 * Start any commands pending resources first.
2152 */
2153 if (tptr->restart_queue) {
2154 inot_private_data_t *restart_queue = tptr->restart_queue;
2155 tptr->restart_queue = NULL;
2156 while (restart_queue) {
2157 ntp = restart_queue;
2158 restart_queue = ntp->rd.nt.nt_hba;
2159 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid);
2160 isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data);
2161 isp_put_ntpd(isp, tptr, ntp);
2162 /*
2163 * If a recursion caused the restart queue to start to fill again,
2164 * stop and splice the new list on top of the old list and restore
2165 * it and go to noresrc.
2166 */
2167 if (tptr->restart_queue) {
2168 if (restart_queue) {
2169 ntp = tptr->restart_queue;
2170 tptr->restart_queue = restart_queue;
2171 while (restart_queue->rd.nt.nt_hba) {
2172 restart_queue = restart_queue->rd.nt.nt_hba;
2173 }
2174 restart_queue->rd.nt.nt_hba = ntp;
2175 }
2176 goto noresrc;
2177 }
2178 }
2179 }
2180
2181 /*
2182 * If the f/w is out of resources, just send a BUSY status back.
2183 */
2184 if (aep->at_rxid == AT7_NORESRC_RXID) {
2185 rls_lun_statep(isp, tptr);
2186 isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
2187 return;
2188 }
2189
2190 /*
2191 * If we're out of resources, just send a BUSY status back.
2192 */
2193 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
2194 if (atiop == NULL) {
2195 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atios", aep->at_rxid);
2196 goto noresrc;
2197 }
2198
2199 atp = isp_get_atpd(isp, tptr, 0);
2200 if (atp == NULL) {
2201 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atps", aep->at_rxid);
2202 goto noresrc;
2203 }
2204 if (isp_get_atpd(isp, tptr, aep->at_rxid)) {
2205 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] tag wraparound in isp_handle_platforms_atio7 (N-Port Handle 0x%04x S_ID 0x%04x OX_ID 0x%04x)\n",
2206 aep->at_rxid, nphdl, sid, aep->at_hdr.ox_id);
2207 /*
2208 * It's not a "no resource" condition- but we can treat it like one
2209 */
2210 goto noresrc;
2211 }
2212
2213 atp->tag = aep->at_rxid;
2214 atp->state = ATPD_STATE_ATIO;
2215 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
2216 tptr->atio_count--;
2217 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, atiop->ccb_h.path, "Take FREE ATIO count now %d\n", tptr->atio_count);
2218 atiop->init_id = nphdl;
2219 atiop->ccb_h.target_id = FCPARAM(isp, chan)->isp_loopid;
2220 atiop->ccb_h.target_lun = lun;
2221 atiop->sense_len = 0;
2222 cdbxlen = aep->at_cmnd.fcp_cmnd_alen_datadir >> FCP_CMND_ADDTL_CDBLEN_SHIFT;
2223 if (cdbxlen) {
2224 isp_prt(isp, ISP_LOGWARN, "additional CDBLEN ignored");
2225 }
2226 cdbxlen = sizeof (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb);
2227 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb, cdbxlen);
2228 atiop->cdb_len = cdbxlen;
2229 atiop->ccb_h.status = CAM_CDB_RECVD;
2230 atiop->tag_id = atp->tag;
2231 switch (aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK) {
2232 case FCP_CMND_TASK_ATTR_SIMPLE:
2233 atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
2234 atiop->tag_action = MSG_SIMPLE_Q_TAG;
2235 break;
2236 case FCP_CMND_TASK_ATTR_HEAD:
2237 atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
2238 atiop->tag_action = MSG_HEAD_OF_Q_TAG;
2239 break;
2240 case FCP_CMND_TASK_ATTR_ORDERED:
2241 atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
2242 atiop->tag_action = MSG_ORDERED_Q_TAG;
2243 break;
2244 default:
2245 /* FALLTHROUGH */
2246 case FCP_CMND_TASK_ATTR_ACA:
2247 case FCP_CMND_TASK_ATTR_UNTAGGED:
2248 atiop->tag_action = 0;
2249 break;
2250 }
2251 atp->orig_datalen = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
2252 atp->bytes_xfered = 0;
2253 atp->last_xframt = 0;
2254 atp->lun = lun;
2255 atp->nphdl = nphdl;
2256 atp->portid = sid;
2257 atp->oxid = aep->at_hdr.ox_id;
2258 atp->cdb0 = atiop->cdb_io.cdb_bytes[0];
2259 atp->tattr = aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK;
2260 atp->state = ATPD_STATE_CAM;
2261 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "ATIO7[%x] CDB=0x%x lun %d datalen %u\n", aep->at_rxid, atp->cdb0, lun, atp->orig_datalen);
2262 xpt_done((union ccb *)atiop);
1697 rls_lun_statep(isp, tptr);
2263 rls_lun_statep(isp, tptr);
1698 return (0);
2264 return;
2265noresrc:
2266 if (atp) {
2267 isp_put_atpd(isp, tptr, atp);
2268 }
2269 ntp = isp_get_ntpd(isp, tptr);
2270 if (ntp == NULL) {
2271 rls_lun_statep(isp, tptr);
2272 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
2273 return;
2274 }
2275 memcpy(ntp->rd.data, aep, QENTRY_LEN);
2276 ntp->rd.nt.nt_hba = tptr->restart_queue;
2277 tptr->restart_queue = ntp;
2278 rls_lun_statep(isp, tptr);
1699}
1700
2279}
2280
1701static int
2281static void
1702isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
1703{
1704 union ccb *ccb;
1705 int sentstatus, ok, notify_cam, resid = 0;
2282isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
2283{
2284 union ccb *ccb;
2285 int sentstatus, ok, notify_cam, resid = 0;
1706 uint16_t tval;
2286 tstate_t *tptr = NULL;
2287 atio_private_data_t *atp = NULL;
2288 int bus;
2289 uint32_t tval, handle;
1707
1708 /*
2290
2291 /*
1709 * CTIO and CTIO2 are close enough....
2292 * CTIO, CTIO2 and CTIO7 are close enough....
1710 */
1711
2293 */
2294
1712 ccb = isp_find_xs_tgt(isp, ((ct_entry_t *)arg)->ct_syshandle);
1713 KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio"));
1714 isp_destroy_tgt_handle(isp, ((ct_entry_t *)arg)->ct_syshandle);
2295 if (IS_SCSI(isp)) {
2296 handle = ((ct_entry_t *)arg)->ct_syshandle;
2297 } else {
2298 handle = ((ct2_entry_t *)arg)->ct_syshandle;
2299 }
2300 ccb = isp_find_xs_tgt(isp, handle);
2301 if (ccb == NULL) {
2302 isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg);
2303 return;
2304 }
2305 isp_destroy_tgt_handle(isp, handle);
2306 bus = XS_CHANNEL(ccb);
2307 tptr = get_lun_statep(isp, bus, XS_LUN(ccb));
2308 if (tptr == NULL) {
2309 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
2310 }
2311 KASSERT((tptr != NULL), ("cannot get state pointer"));
2312 if (isp->isp_nactive) {
2313 isp->isp_nactive++;
2314 }
2315 if (IS_24XX(isp)) {
2316 ct7_entry_t *ct = arg;
1715
2317
1716 if (IS_FC(isp)) {
2318 atp = isp_get_atpd(isp, tptr, ct->ct_rxid);
2319 if (atp == NULL) {
2320 rls_lun_statep(isp, tptr);
2321 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ct->ct_rxid);
2322 return;
2323 }
2324
2325 sentstatus = ct->ct_flags & CT7_SENDSTATUS;
2326 ok = (ct->ct_nphdl == CT7_OK);
2327 if (ok && sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) {
2328 ccb->ccb_h.status |= CAM_SENT_SENSE;
2329 }
2330 notify_cam = ct->ct_header.rqs_seqno & 0x1;
2331 if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) {
2332 resid = ct->ct_resid;
2333 atp->bytes_xfered += (atp->last_xframt - resid);
2334 atp->last_xframt = 0;
2335 }
2336 if (ct->ct_nphdl == CT_HBA_RESET) {
2337 ok = 0;
2338 notify_cam = 1;
2339 sentstatus = 1;
2340 ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR;
2341 } else if (!ok) {
2342 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
2343 }
2344 tval = atp->tag;
2345 isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO7[%x] sts 0x%x flg 0x%x sns %d resid %d %s", __func__,
2346 ct->ct_rxid, ct->ct_nphdl, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
2347 atp->state = ATPD_STATE_PDON; /* XXX: should really come after isp_complete_ctio */
2348 } else if (IS_FC(isp)) {
1717 ct2_entry_t *ct = arg;
2349 ct2_entry_t *ct = arg;
1718 atio_private_data_t *atp = isp_get_atpd(isp, ct->ct_rxid);
2350
2351 atp = isp_get_atpd(isp, tptr, ct->ct_rxid);
1719 if (atp == NULL) {
2352 if (atp == NULL) {
1720 isp_prt(isp, ISP_LOGERR,
1721 "cannot find adjunct for %x after I/O",
1722 ct->ct_rxid);
1723 return (0);
2353 rls_lun_statep(isp, tptr);
2354 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ct->ct_rxid);
2355 return;
1724 }
1725 sentstatus = ct->ct_flags & CT2_SENDSTATUS;
1726 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
1727 if (ok && sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) {
1728 ccb->ccb_h.status |= CAM_SENT_SENSE;
1729 }
1730 notify_cam = ct->ct_header.rqs_seqno & 0x1;
1731 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1732 resid = ct->ct_resid;
1733 atp->bytes_xfered += (atp->last_xframt - resid);
1734 atp->last_xframt = 0;
1735 }
2356 }
2357 sentstatus = ct->ct_flags & CT2_SENDSTATUS;
2358 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
2359 if (ok && sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) {
2360 ccb->ccb_h.status |= CAM_SENT_SENSE;
2361 }
2362 notify_cam = ct->ct_header.rqs_seqno & 0x1;
2363 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
2364 resid = ct->ct_resid;
2365 atp->bytes_xfered += (atp->last_xframt - resid);
2366 atp->last_xframt = 0;
2367 }
1736 if (sentstatus || !ok) {
1737 atp->tag = 0;
2368 if (ct->ct_status == CT_HBA_RESET) {
2369 ok = 0;
2370 notify_cam = 1;
2371 sentstatus = 1;
2372 ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR;
2373 } else if (!ok) {
2374 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1738 }
2375 }
1739 isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN,
1740 "CTIO2[%x] sts 0x%x flg 0x%x sns %d resid %d %s",
1741 ct->ct_rxid, ct->ct_status, ct->ct_flags,
1742 (ccb->ccb_h.status & CAM_SENT_SENSE) != 0,
1743 resid, sentstatus? "FIN" : "MID");
1744 tval = ct->ct_rxid;
1745
1746 /* XXX: should really come after isp_complete_ctio */
1747 atp->state = ATPD_STATE_PDON;
2376 isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO2[%x] sts 0x%x flg 0x%x sns %d resid %d %s", __func__,
2377 ct->ct_rxid, ct->ct_status, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
2378 tval = atp->tag;
2379 atp->state = ATPD_STATE_PDON; /* XXX: should really come after isp_complete_ctio */
1748 } else {
1749 ct_entry_t *ct = arg;
1750 sentstatus = ct->ct_flags & CT_SENDSTATUS;
1751 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
1752 /*
1753 * We *ought* to be able to get back to the original ATIO
1754 * here, but for some reason this gets lost. It's just as
1755 * well because it's squirrelled away as part of periph
1756 * private data.
1757 *
1758 * We can live without it as long as we continue to use
1759 * the auto-replenish feature for CTIOs.
1760 */
1761 notify_cam = ct->ct_header.rqs_seqno & 0x1;
2380 } else {
2381 ct_entry_t *ct = arg;
2382 sentstatus = ct->ct_flags & CT_SENDSTATUS;
2383 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
2384 /*
2385 * We *ought* to be able to get back to the original ATIO
2386 * here, but for some reason this gets lost. It's just as
2387 * well because it's squirrelled away as part of periph
2388 * private data.
2389 *
2390 * We can live without it as long as we continue to use
2391 * the auto-replenish feature for CTIOs.
2392 */
2393 notify_cam = ct->ct_header.rqs_seqno & 0x1;
1762 if (ct->ct_status & QLTM_SVALID) {
2394 if (ct->ct_status == (CT_HBA_RESET & 0xff)) {
2395 ok = 0;
2396 notify_cam = 1;
2397 sentstatus = 1;
2398 ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR;
2399 } else if (!ok) {
2400 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
2401 } else if (ct->ct_status & QLTM_SVALID) {
1763 char *sp = (char *)ct;
1764 sp += CTIO_SENSE_OFFSET;
2402 char *sp = (char *)ct;
2403 sp += CTIO_SENSE_OFFSET;
1765 ccb->csio.sense_len =
1766 min(sizeof (ccb->csio.sense_data), QLTM_SENSELEN);
1767 MEMCPY(&ccb->csio.sense_data, sp, ccb->csio.sense_len);
2404 ccb->csio.sense_len = min(sizeof (ccb->csio.sense_data), QLTM_SENSELEN);
2405 ISP_MEMCPY(&ccb->csio.sense_data, sp, ccb->csio.sense_len);
1768 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
1769 }
1770 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1771 resid = ct->ct_resid;
1772 }
2406 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
2407 }
2408 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
2409 resid = ct->ct_resid;
2410 }
1773 isp_prt(isp, ISP_LOGTDEBUG0,
1774 "CTIO[%x] tag %x iid %d lun %d sts %x flg %x resid %d %s",
1775 ct->ct_fwhandle, ct->ct_tag_val, ct->ct_iid, ct->ct_lun,
1776 ct->ct_status, ct->ct_flags, resid,
1777 sentstatus? "FIN" : "MID");
2411 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO[%x] tag %x S_ID 0x%x lun %d sts %x flg %x resid %d %s", __func__,
2412 ct->ct_fwhandle, ct->ct_tag_val, ct->ct_iid, ct->ct_lun, ct->ct_status, ct->ct_flags, resid, sentstatus? "FIN" : "MID");
1778 tval = ct->ct_fwhandle;
1779 }
1780 ccb->csio.resid += resid;
1781
1782 /*
1783 * We're here either because intermediate data transfers are done
1784 * and/or the final status CTIO (which may have joined with a
1785 * Data Transfer) is done.
1786 *
1787 * In any case, for this platform, the upper layers figure out
1788 * what to do next, so all we do here is collect status and
1789 * pass information along. Any DMA handles have already been
1790 * freed.
1791 */
1792 if (notify_cam == 0) {
1793 isp_prt(isp, ISP_LOGTDEBUG0, " INTER CTIO[0x%x] done", tval);
2413 tval = ct->ct_fwhandle;
2414 }
2415 ccb->csio.resid += resid;
2416
2417 /*
2418 * We're here either because intermediate data transfers are done
2419 * and/or the final status CTIO (which may have joined with a
2420 * Data Transfer) is done.
2421 *
2422 * In any case, for this platform, the upper layers figure out
2423 * what to do next, so all we do here is collect status and
2424 * pass information along. Any DMA handles have already been
2425 * freed.
2426 */
2427 if (notify_cam == 0) {
2428 isp_prt(isp, ISP_LOGTDEBUG0, " INTER CTIO[0x%x] done", tval);
1794 return (0);
2429 return;
1795 }
2430 }
2431 if (tptr) {
2432 rls_lun_statep(isp, tptr);
2433 }
2434 isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done", (sentstatus)? " FINAL " : "MIDTERM ", tval);
1796
2435
1797 isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done",
1798 (sentstatus)? " FINAL " : "MIDTERM ", tval);
1799
1800 if (!ok) {
2436 if (!ok && !IS_24XX(isp)) {
1801 isp_target_putback_atio(ccb);
1802 } else {
1803 isp_complete_ctio(ccb);
2437 isp_target_putback_atio(ccb);
2438 } else {
2439 isp_complete_ctio(ccb);
1804
1805 }
2440 }
1806 return (0);
1807}
1808
2441}
2442
1809static int
1810isp_handle_platform_notify_scsi(ispsoftc_t *isp, in_entry_t *inp)
2443static void
2444isp_handle_platform_notify_scsi(ispsoftc_t *isp, in_entry_t *inot)
1811{
2445{
1812 return (0); /* XXXX */
2446 (void) isp_notify_ack(isp, inot);
1813}
1814
2447}
2448
1815static int
2449static void
1816isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
1817{
2450isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
2451{
1818
2452 int needack = 1;
1819 switch (inp->in_status) {
1820 case IN_PORT_LOGOUT:
2453 switch (inp->in_status) {
2454 case IN_PORT_LOGOUT:
1821 isp_prt(isp, ISP_LOGWARN, "port logout of iid %d",
1822 inp->in_iid);
2455 /*
2456 * XXX: Need to delete this initiator's WWN from the database
2457 * XXX: Need to send this LOGOUT upstream
2458 */
2459 isp_prt(isp, ISP_LOGWARN, "port logout of S_ID 0x%x", inp->in_iid);
1823 break;
1824 case IN_PORT_CHANGED:
2460 break;
2461 case IN_PORT_CHANGED:
1825 isp_prt(isp, ISP_LOGWARN, "port changed for iid %d",
1826 inp->in_iid);
2462 isp_prt(isp, ISP_LOGWARN, "port changed for S_ID 0x%x", inp->in_iid);
1827 break;
1828 case IN_GLOBAL_LOGO:
2463 break;
2464 case IN_GLOBAL_LOGO:
2465 isp_del_all_wwn_entries(isp, 0);
1829 isp_prt(isp, ISP_LOGINFO, "all ports logged out");
1830 break;
1831 case IN_ABORT_TASK:
1832 {
2466 isp_prt(isp, ISP_LOGINFO, "all ports logged out");
2467 break;
2468 case IN_ABORT_TASK:
2469 {
1833 atio_private_data_t *atp = isp_get_atpd(isp, inp->in_seqid);
1834 struct ccb_immed_notify *inot = NULL;
2470 tstate_t *tptr;
2471 uint16_t lun;
2472 uint32_t loopid;
2473 uint64_t wwn;
2474 atio_private_data_t *atp;
2475 fcportdb_t *lp;
2476 struct ccb_immediate_notify *inot = NULL;
1835
2477
2478 if (ISP_CAP_SCCFW(isp)) {
2479 lun = inp->in_scclun;
2480 } else {
2481 lun = inp->in_lun;
2482 }
2483 if (ISP_CAP_2KLOGIN(isp)) {
2484 loopid = ((in_fcentry_e_t *)inot)->in_iid;
2485 } else {
2486 loopid = inp->in_iid;
2487 }
2488 if (isp_find_pdb_by_loopid(isp, 0, loopid, &lp)) {
2489 wwn = lp->port_wwn;
2490 } else {
2491 wwn = INI_ANY;
2492 }
2493 tptr = get_lun_statep(isp, 0, lun);
2494 if (tptr == NULL) {
2495 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
2496 if (tptr == NULL) {
2497 isp_prt(isp, ISP_LOGWARN, "ABORT TASK for lun %u- but no tstate", lun);
2498 return;
2499 }
2500 }
2501 atp = isp_get_atpd(isp, tptr, inp->in_seqid);
2502
1836 if (atp) {
2503 if (atp) {
1837 tstate_t *tptr = get_lun_statep(isp, 0, atp->lun);
1838 if (tptr) {
1839 inot = (struct ccb_immed_notify *)
1840 SLIST_FIRST(&tptr->inots);
1841 if (inot) {
1842 tptr->inot_count--;
1843 SLIST_REMOVE_HEAD(&tptr->inots,
1844 sim_links.sle);
1845 isp_prt(isp, ISP_LOGTDEBUG0,
1846 "Take FREE INOT count now %d",
1847 tptr->inot_count);
1848 }
2504 inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots);
2505 isp_prt(isp, ISP_LOGTDEBUG0, "ABORT TASK RX_ID %x WWN 0x%016llx state %d", inp->in_seqid, (unsigned long long) wwn, atp->state);
2506 if (inot) {
2507 tptr->inot_count--;
2508 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
2509 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count);
2510 } else {
2511 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "out of INOT structures\n");
1849 }
2512 }
1850 isp_prt(isp, ISP_LOGWARN,
1851 "abort task RX_ID %x IID %d state %d",
1852 inp->in_seqid, inp->in_iid, atp->state);
1853 } else {
2513 } else {
1854 isp_prt(isp, ISP_LOGWARN,
1855 "abort task RX_ID %x from iid %d, state unknown",
1856 inp->in_seqid, inp->in_iid);
2514 ISP_PATH_PRT(isp, ISP_LOGWARN, tptr->owner, "abort task RX_ID %x from wwn 0x%016llx, state unknown\n", inp->in_seqid, wwn);
1857 }
1858 if (inot) {
2515 }
2516 if (inot) {
1859 inot->initiator_id = inp->in_iid;
1860 inot->sense_len = 0;
1861 inot->message_args[0] = MSG_ABORT_TAG;
1862 inot->message_args[1] = inp->in_seqid & 0xff;
1863 inot->message_args[2] = (inp->in_seqid >> 8) & 0xff;
1864 inot->ccb_h.status = CAM_MESSAGE_RECV;
1865 xpt_done((union ccb *)inot);
2517 isp_notify_t tmp, *nt = &tmp;
2518 ISP_MEMZERO(nt, sizeof (isp_notify_t));
2519 nt->nt_hba = isp;
2520 nt->nt_tgt = FCPARAM(isp, 0)->isp_wwpn;
2521 nt->nt_wwn = wwn;
2522 nt->nt_nphdl = loopid;
2523 nt->nt_sid = PORT_ANY;
2524 nt->nt_did = PORT_ANY;
2525 nt->nt_lun = lun;
2526 nt->nt_need_ack = 1;
2527 nt->nt_channel = 0;
2528 nt->nt_ncode = NT_ABORT_TASK;
2529 nt->nt_lreserved = inot;
2530 isp_handle_platform_target_tmf(isp, nt);
2531 needack = 0;
1866 }
2532 }
2533 rls_lun_statep(isp, tptr);
1867 break;
1868 }
1869 default:
1870 break;
1871 }
2534 break;
2535 }
2536 default:
2537 break;
2538 }
2539 if (needack) {
2540 (void) isp_notify_ack(isp, inp);
2541 }
2542}
2543
2544static void
2545isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot)
2546{
2547 uint16_t nphdl;
2548 uint32_t portid;
2549 fcportdb_t *lp;
2550 uint8_t *ptr = NULL;
2551 uint64_t wwn;
2552
2553 nphdl = inot->in_nphdl;
2554 if (nphdl != NIL_HANDLE) {
2555 portid = inot->in_portid_hi << 16 | inot->in_portid_lo;
2556 } else {
2557 portid = PORT_ANY;
2558 }
2559
2560 switch (inot->in_status) {
2561 case IN24XX_ELS_RCVD:
2562 {
2563 char buf[16], *msg;
2564 int chan = ISP_GET_VPIDX(isp, inot->in_vpidx);
2565
2566 /*
2567 * Note that we're just getting notification that an ELS was received
2568 * (possibly with some associcated information sent upstream). This is
2569 * *not* the same as being given the ELS frame to accept or reject.
2570 */
2571 switch (inot->in_status_subcode) {
2572 case LOGO:
2573 msg = "LOGO";
2574 if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) {
2575 ptr = (uint8_t *)inot; /* point to unswizzled entry! */
2576 wwn = (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF]) << 56) |
2577 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+1]) << 48) |
2578 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+2]) << 40) |
2579 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+3]) << 32) |
2580 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+4]) << 24) |
2581 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+5]) << 16) |
2582 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+6]) << 8) |
2583 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+7]));
2584 } else {
2585 wwn = INI_ANY;
2586 }
2587 isp_del_wwn_entry(isp, chan, wwn, nphdl, portid);
2588 break;
2589 case PRLO:
2590 msg = "PRLO";
2591 break;
2592 case PLOGI:
2593 msg = "PLOGI";
2594 if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) {
2595 ptr = (uint8_t *)inot; /* point to unswizzled entry! */
2596 wwn = (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF]) << 56) |
2597 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+1]) << 48) |
2598 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+2]) << 40) |
2599 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+3]) << 32) |
2600 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+4]) << 24) |
2601 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+5]) << 16) |
2602 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+6]) << 8) |
2603 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+7]));
2604 } else {
2605 wwn = INI_NONE;
2606 }
2607 isp_add_wwn_entry(isp, chan, wwn, nphdl, portid);
2608 break;
2609 case PRLI:
2610 msg = "PRLI";
2611 break;
2612 case PDISC:
2613 msg = "PDISC";
2614 break;
2615 case ADISC:
2616 msg = "ADISC";
2617 break;
2618 default:
2619 ISP_SNPRINTF(buf, sizeof (buf), "ELS 0x%x", inot->in_status_subcode);
2620 msg = buf;
2621 break;
2622 }
2623 if (inot->in_flags & IN24XX_FLAG_PUREX_IOCB) {
2624 isp_prt(isp, ISP_LOGERR, "%s Chan %d ELS N-port handle %x PortID 0x%06x marked as needing a PUREX response", msg, chan, nphdl, portid);
2625 break;
2626 }
2627 isp_prt(isp, ISP_LOGTDEBUG0, "%s Chan %d ELS N-port handle %x PortID 0x%06x RX_ID 0x%x OX_ID 0x%x", msg, chan, nphdl, portid,
2628 inot->in_rxid, inot->in_oxid);
2629 (void) isp_notify_ack(isp, inot);
2630 break;
2631 }
2632
2633 case IN24XX_PORT_LOGOUT:
2634 ptr = "PORT LOGOUT";
2635 if (isp_find_pdb_by_loopid(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, &lp)) {
2636 isp_del_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), lp->port_wwn, nphdl, lp->portid);
2637 }
2638 /* FALLTHROUGH */
2639 case IN24XX_PORT_CHANGED:
2640 if (ptr == NULL) {
2641 ptr = "PORT CHANGED";
2642 }
2643 /* FALLTHROUGH */
2644 case IN24XX_LIP_RESET:
2645 if (ptr == NULL) {
2646 ptr = "LIP RESET";
2647 }
2648 isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for N-port handle 0x%x", ISP_GET_VPIDX(isp, inot->in_vpidx), ptr, inot->in_status_subcode, nphdl);
2649
2650 /*
2651 * All subcodes here are irrelevant. What is relevant
2652 * is that we need to terminate all active commands from
2653 * this initiator (known by N-port handle).
2654 */
2655 /* XXX IMPLEMENT XXX */
2656 (void) isp_notify_ack(isp, inot);
2657 break;
2658
2659 case IN24XX_LINK_RESET:
2660 case IN24XX_LINK_FAILED:
2661 case IN24XX_SRR_RCVD:
2662 default:
2663 (void) isp_notify_ack(isp, inot);
2664 break;
2665 }
2666}
2667
2668static int
2669isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp)
2670{
2671
2672 if (isp->isp_state != ISP_RUNSTATE) {
2673 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", mp->nt_ncode, mp->nt_lreserved != NULL);
2674 return (0);
2675 }
2676
2677 /*
2678 * This case is for a Task Management Function, which shows up as an ATIO7 entry.
2679 */
2680 if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ATIO) {
2681 ct7_entry_t local, *cto = &local;
2682 at7_entry_t *aep = (at7_entry_t *)mp->nt_lreserved;
2683 fcportdb_t *lp;
2684 uint32_t sid;
2685 uint16_t nphdl;
2686
2687 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
2688 if (isp_find_pdb_by_sid(isp, mp->nt_channel, sid, &lp)) {
2689 nphdl = lp->handle;
2690 } else {
2691 nphdl = NIL_HANDLE;
2692 }
2693 ISP_MEMZERO(&local, sizeof (local));
2694 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
2695 cto->ct_header.rqs_entry_count = 1;
2696 cto->ct_nphdl = nphdl;
2697 cto->ct_rxid = aep->at_rxid;
2698 cto->ct_vpidx = mp->nt_channel;
2699 cto->ct_iid_lo = sid;
2700 cto->ct_iid_hi = sid >> 16;
2701 cto->ct_oxid = aep->at_hdr.ox_id;
2702 cto->ct_flags = CT7_SENDSTATUS|CT7_NOACK|CT7_NO_DATA|CT7_FLAG_MODE1;
2703 cto->ct_flags |= (aep->at_ta_len >> 12) << CT7_TASK_ATTR_SHIFT;
2704 return (isp_target_put_entry(isp, &local));
2705 }
2706
2707 /*
2708 * This case is for a responding to an ABTS frame
2709 */
2710 if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
2711
2712 /*
2713 * Overload nt_need_ack here to mark whether we've terminated the associated command.
2714 */
2715 if (mp->nt_need_ack) {
2716 uint8_t storage[QENTRY_LEN];
2717 ct7_entry_t *cto = (ct7_entry_t *) storage;
2718 abts_t *abts = (abts_t *)mp->nt_lreserved;
2719
2720 ISP_MEMZERO(cto, sizeof (ct7_entry_t));
2721 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [%x] terminating after ABTS received", __func__, abts->abts_rxid_task);
2722 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
2723 cto->ct_header.rqs_entry_count = 1;
2724 cto->ct_nphdl = mp->nt_nphdl;
2725 cto->ct_rxid = abts->abts_rxid_task;
2726 cto->ct_iid_lo = mp->nt_sid;
2727 cto->ct_iid_hi = mp->nt_sid >> 16;
2728 cto->ct_oxid = abts->abts_ox_id;
2729 cto->ct_vpidx = mp->nt_channel;
2730 cto->ct_flags = CT7_NOACK|CT7_TERMINATE;
2731 if (isp_target_put_entry(isp, cto)) {
2732 return (ENOMEM);
2733 }
2734 mp->nt_need_ack = 0;
2735 }
2736 if (isp_acknak_abts(isp, mp->nt_lreserved, 0) == ENOMEM) {
2737 return (ENOMEM);
2738 } else {
2739 return (0);
2740 }
2741 }
2742
2743 /*
2744 * Handle logout cases here
2745 */
2746 if (mp->nt_ncode == NT_GLOBAL_LOGOUT) {
2747 isp_del_all_wwn_entries(isp, mp->nt_channel);
2748 }
2749
2750 if (mp->nt_ncode == NT_LOGOUT) {
2751 if (!IS_2100(isp) && IS_FC(isp)) {
2752 isp_del_wwn_entries(isp, mp);
2753 }
2754 }
2755
2756 /*
2757 * General purpose acknowledgement
2758 */
2759 if (mp->nt_need_ack) {
2760 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) being acked", mp->nt_ncode, mp->nt_lreserved != NULL);
2761 return (isp_notify_ack(isp, mp->nt_lreserved));
2762 }
1872 return (0);
1873}
2763 return (0);
2764}
2765
2766/*
2767 * Handle task managment functions.
2768 *
2769 * We show up here with a notify structure filled out.
2770 *
2771 * The nt_lreserved tag points to the original queue entry
2772 */
2773static void
2774isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify)
2775{
2776 tstate_t *tptr;
2777 fcportdb_t *lp;
2778 struct ccb_immediate_notify *inot;
2779 inot_private_data_t *ntp = NULL;
2780 lun_id_t lun;
2781
2782 isp_prt(isp, ISP_LOGTDEBUG0, "%s: code 0x%x sid 0x%x tagval 0x%016llx chan %d lun 0x%x", __func__, notify->nt_ncode,
2783 notify->nt_sid, (unsigned long long) notify->nt_tagval, notify->nt_channel, notify->nt_lun);
2784 /*
2785 * NB: This assignment is necessary because of tricky type conversion.
2786 * XXX: This is tricky and I need to check this. If the lun isn't known
2787 * XXX: for the task management function, it does not of necessity follow
2788 * XXX: that it should go up stream to the wildcard listener.
2789 */
2790 if (notify->nt_lun == LUN_ANY) {
2791 lun = CAM_LUN_WILDCARD;
2792 } else {
2793 lun = notify->nt_lun;
2794 }
2795 tptr = get_lun_statep(isp, notify->nt_channel, lun);
2796 if (tptr == NULL) {
2797 tptr = get_lun_statep(isp, notify->nt_channel, CAM_LUN_WILDCARD);
2798 if (tptr == NULL) {
2799 isp_prt(isp, ISP_LOGWARN, "%s: no state pointer found for chan %d lun 0x%x", __func__, notify->nt_channel, lun);
2800 goto bad;
2801 }
2802 }
2803 inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots);
2804 if (inot == NULL) {
2805 isp_prt(isp, ISP_LOGWARN, "%s: out of immediate notify structures for chan %d lun 0x%x", __func__, notify->nt_channel, lun);
2806 goto bad;
2807 }
2808
2809 if (isp_find_pdb_by_sid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0) {
2810 inot->initiator_id = CAM_TARGET_WILDCARD;
2811 } else {
2812 inot->initiator_id = lp->handle;
2813 }
2814 inot->seq_id = notify->nt_tagval;
2815 inot->tag_id = notify->nt_tagval >> 32;
2816
2817 switch (notify->nt_ncode) {
2818 case NT_ABORT_TASK:
2819 isp_target_mark_aborted_early(isp, tptr, inot->tag_id);
2820 inot->arg = MSG_ABORT_TASK;
2821 break;
2822 case NT_ABORT_TASK_SET:
2823 isp_target_mark_aborted_early(isp, tptr, TAG_ANY);
2824 inot->arg = MSG_ABORT_TASK_SET;
2825 break;
2826 case NT_CLEAR_ACA:
2827 inot->arg = MSG_CLEAR_ACA;
2828 break;
2829 case NT_CLEAR_TASK_SET:
2830 inot->arg = MSG_CLEAR_TASK_SET;
2831 break;
2832 case NT_LUN_RESET:
2833 inot->arg = MSG_LOGICAL_UNIT_RESET;
2834 break;
2835 case NT_TARGET_RESET:
2836 inot->arg = MSG_TARGET_RESET;
2837 break;
2838 default:
2839 isp_prt(isp, ISP_LOGWARN, "%s: unknown TMF code 0x%x for chan %d lun 0x%x", __func__, notify->nt_ncode, notify->nt_channel, lun);
2840 goto bad;
2841 }
2842
2843 ntp = isp_get_ntpd(isp, tptr);
2844 if (ntp == NULL) {
2845 isp_prt(isp, ISP_LOGWARN, "%s: out of inotify private structures", __func__);
2846 goto bad;
2847 }
2848 ISP_MEMCPY(&ntp->rd.nt, notify, sizeof (isp_notify_t));
2849 if (notify->nt_lreserved) {
2850 ISP_MEMCPY(&ntp->rd.data, notify->nt_lreserved, QENTRY_LEN);
2851 ntp->rd.nt.nt_lreserved = &ntp->rd.data;
2852 }
2853 ntp->rd.seq_id = notify->nt_tagval;
2854 ntp->rd.tag_id = notify->nt_tagval >> 32;
2855
2856 tptr->inot_count--;
2857 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
2858 rls_lun_statep(isp, tptr);
2859 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count);
2860 inot->ccb_h.status = CAM_MESSAGE_RECV;
2861 xpt_done((union ccb *)inot);
2862 return;
2863bad:
2864 if (tptr) {
2865 rls_lun_statep(isp, tptr);
2866 }
2867 if (notify->nt_need_ack && notify->nt_lreserved) {
2868 if (((isphdr_t *)notify->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
2869 (void) isp_acknak_abts(isp, notify->nt_lreserved, ENOMEM);
2870 } else {
2871 (void) isp_notify_ack(isp, notify->nt_lreserved);
2872 }
2873 }
2874}
2875
2876/*
2877 * Find the associated private data and makr it as dead so
2878 * we don't try to work on it any further.
2879 */
2880static void
2881isp_target_mark_aborted(ispsoftc_t *isp, union ccb *ccb)
2882{
2883 tstate_t *tptr;
2884 atio_private_data_t *atp;
2885
2886 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
2887 if (tptr == NULL) {
2888 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
2889 if (tptr == NULL) {
2890 ccb->ccb_h.status = CAM_REQ_INVALID;
2891 return;
2892 }
2893 }
2894
2895 atp = isp_get_atpd(isp, tptr, ccb->atio.tag_id);
2896 if (atp == NULL) {
2897 ccb->ccb_h.status = CAM_REQ_INVALID;
2898 return;
2899 }
2900 atp->dead = 1;
2901 ccb->ccb_h.status = CAM_REQ_CMP;
2902}
2903
2904static void
2905isp_target_mark_aborted_early(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id)
2906{
2907 atio_private_data_t *atp;
2908 inot_private_data_t *restart_queue = tptr->restart_queue;
2909
2910 /*
2911 * First, clean any commands pending restart
2912 */
2913 tptr->restart_queue = NULL;
2914 while (restart_queue) {
2915 uint32_t this_tag_id;
2916 inot_private_data_t *ntp = restart_queue;
2917
2918 restart_queue = ntp->rd.nt.nt_hba;
2919
2920 if (IS_24XX(isp)) {
2921 this_tag_id = ((at7_entry_t *)ntp->rd.data)->at_rxid;
2922 } else {
2923 this_tag_id = ((at2_entry_t *)ntp->rd.data)->at_rxid;
2924 }
2925 if ((uint64_t)tag_id == TAG_ANY || tag_id == this_tag_id) {
2926 isp_put_ntpd(isp, tptr, ntp);
2927 } else {
2928 ntp->rd.nt.nt_hba = tptr->restart_queue;
2929 tptr->restart_queue = ntp;
2930 }
2931 }
2932
2933 /*
2934 * Now mark other ones dead as well.
2935 */
2936 for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
2937 if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id) {
2938 atp->dead = 1;
2939 }
2940 }
2941}
2942
2943
2944#ifdef ISP_INTERNAL_TARGET
2945// #define ISP_FORCE_TIMEOUT 1
2946#define ISP_TEST_WWNS 1
2947#define ISP_TEST_SEPARATE_STATUS 1
2948
2949#define ccb_data_offset ppriv_field0
2950#define ccb_atio ppriv_ptr1
2951#define ccb_inot ppriv_ptr1
2952
2953#define MAX_ISP_TARG_TRANSFER (2 << 20)
2954#define NISP_TARG_CMDS 1024
2955#define NISP_TARG_NOTIFIES 1024
2956#define DISK_SHIFT 9
2957#define JUNK_SIZE 256
2958
2959#ifndef VERIFY_10
2960#define VERIFY_10 0x2f
1874#endif
1875
2961#endif
2962
2963TAILQ_HEAD(ccb_queue, ccb_hdr);
2964extern u_int vm_kmem_size;
2965static int ca;
2966static uint32_t disk_size;
2967static uint8_t *disk_data = NULL;
2968static uint8_t *junk_data;
2969static MALLOC_DEFINE(M_ISPTARG, "ISPTARG", "ISP TARGET data");
2970struct isptarg_softc {
2971 /* CCBs (CTIOs, ATIOs, INOTs) pending on the controller */
2972 struct ccb_queue work_queue;
2973 struct ccb_queue rework_queue;
2974 struct ccb_queue running_queue;
2975 struct ccb_queue inot_queue;
2976 struct cam_periph *periph;
2977 struct cam_path *path;
2978 ispsoftc_t *isp;
2979};
2980static periph_ctor_t isptargctor;
2981static periph_dtor_t isptargdtor;
2982static periph_start_t isptargstart;
2983static periph_init_t isptarginit;
2984static void isptarg_done(struct cam_periph *, union ccb *);
2985static void isptargasync(void *, u_int32_t, struct cam_path *, void *);
2986
2987
2988static int isptarg_rwparm(uint8_t *, uint8_t *, uint64_t, uint32_t, uint8_t **, uint32_t *, int *);
2989
2990static struct periph_driver isptargdriver =
2991{
2992 isptarginit, "isptarg", TAILQ_HEAD_INITIALIZER(isptargdriver.units), /* generation */ 0
2993};
2994
1876static void
2995static void
2996isptarginit(void)
2997{
2998}
2999
3000static void
3001isptargnotify(ispsoftc_t *isp, union ccb *iccb, struct ccb_immediate_notify *inot)
3002{
3003 struct ccb_notify_acknowledge *ack = &iccb->cna2;
3004
3005 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, inot->ccb_h.path, "%s: [0x%x] immediate notify for 0x%x from 0x%x status 0x%x arg 0x%x\n", __func__,
3006 inot->tag_id, inot->initiator_id, inot->seq_id, inot->ccb_h.status, inot->arg);
3007 ack->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE;
3008 ack->ccb_h.flags = 0;
3009 ack->ccb_h.retry_count = 0;
3010 ack->ccb_h.cbfcnp = isptarg_done;
3011 ack->ccb_h.timeout = 0;
3012 ack->ccb_h.ccb_inot = inot;
3013 ack->tag_id = inot->tag_id;
3014 ack->seq_id = inot->seq_id;
3015 ack->initiator_id = inot->initiator_id;
3016 xpt_action(iccb);
3017}
3018
3019static void
3020isptargstart(struct cam_periph *periph, union ccb *iccb)
3021{
3022 const uint8_t niliqd[SHORT_INQUIRY_LENGTH] = { 0x7f };
3023 const uint8_t iqd[SHORT_INQUIRY_LENGTH] = {
3024 0, 0x0, 0x2, 0x2, 32, 0, 0, 0x32,
3025 'F', 'R', 'E', 'E', 'B', 'S', 'D', ' ',
3026 'S', 'C', 'S', 'I', ' ', 'M', 'E', 'M',
3027 'O', 'R', 'Y', ' ', 'D', 'I', 'S', 'K',
3028 '0', '0', '0', '1'
3029 };
3030 int i, more = 0, last;
3031 struct isptarg_softc *softc = periph->softc;
3032 struct ccb_scsiio *csio;
3033 lun_id_t return_lun;
3034 struct ccb_accept_tio *atio;
3035 uint8_t *cdb, *ptr, status;
3036 uint8_t *data_ptr;
3037 uint32_t data_len, flags;
3038 struct ccb_hdr *ccbh;
3039
3040 mtx_assert(periph->sim->mtx, MA_OWNED);
3041 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, iccb->ccb_h.path, "%s: function code 0x%x INOTQ=%c WORKQ=%c REWORKQ=%c\n", __func__, iccb->ccb_h.func_code,
3042 TAILQ_FIRST(&softc->inot_queue)? 'y' : 'n', TAILQ_FIRST(&softc->work_queue)? 'y' : 'n', TAILQ_FIRST(&softc->rework_queue)? 'y' : 'n');
3043 /*
3044 * Check for immediate notifies first
3045 */
3046 ccbh = TAILQ_FIRST(&softc->inot_queue);
3047 if (ccbh) {
3048 TAILQ_REMOVE(&softc->inot_queue, ccbh, periph_links.tqe);
3049 if (TAILQ_FIRST(&softc->inot_queue) || TAILQ_FIRST(&softc->work_queue) || TAILQ_FIRST(&softc->rework_queue)) {
3050 xpt_schedule(periph, 1);
3051 }
3052 isptargnotify(softc->isp, iccb, (struct ccb_immediate_notify *)ccbh);
3053 return;
3054 }
3055
3056 /*
3057 * Check the rework (continuation) work queue first.
3058 */
3059 ccbh = TAILQ_FIRST(&softc->rework_queue);
3060 if (ccbh) {
3061 atio = (struct ccb_accept_tio *)ccbh;
3062 TAILQ_REMOVE(&softc->rework_queue, ccbh, periph_links.tqe);
3063 more = TAILQ_FIRST(&softc->work_queue) || TAILQ_FIRST(&softc->rework_queue);
3064 } else {
3065 ccbh = TAILQ_FIRST(&softc->work_queue);
3066 if (ccbh == NULL) {
3067 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, iccb->ccb_h.path, "%s: woken up but no work?\n", __func__);
3068 xpt_release_ccb(iccb);
3069 return;
3070 }
3071 atio = (struct ccb_accept_tio *)ccbh;
3072 TAILQ_REMOVE(&softc->work_queue, ccbh, periph_links.tqe);
3073 more = TAILQ_FIRST(&softc->work_queue) != NULL;
3074 atio->ccb_h.ccb_data_offset = 0;
3075 }
3076
3077 if (atio->tag_id == 0xffffffff || atio->ccb_h.func_code != XPT_ACCEPT_TARGET_IO) {
3078 panic("BAD ATIO");
3079 }
3080
3081 data_ptr = NULL;
3082 data_len = 0;
3083 csio = &iccb->csio;
3084 status = SCSI_STATUS_OK;
3085 flags = CAM_SEND_STATUS;
3086 memset(&atio->sense_data, 0, sizeof (atio->sense_data));
3087 cdb = atio->cdb_io.cdb_bytes;
3088 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, ccbh->path, "%s: [0x%x] processing ATIO from 0x%x CDB=0x%x data_offset=%u\n", __func__, atio->tag_id, atio->init_id,
3089 cdb[0], atio->ccb_h.ccb_data_offset);
3090
3091 return_lun = XS_LUN(atio);
3092 if (return_lun != 0) {
3093 xpt_print(atio->ccb_h.path, "[0x%x] Non-Zero Lun %d: cdb0=0x%x\n", atio->tag_id, return_lun, cdb[0]);
3094 if (cdb[0] != INQUIRY && cdb[0] != REPORT_LUNS && cdb[0] != REQUEST_SENSE) {
3095 status = SCSI_STATUS_CHECK_COND;
3096 atio->sense_data.error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_ILLEGAL_REQUEST;
3097 atio->sense_data.add_sense_code = 0x25;
3098 atio->sense_data.add_sense_code_qual = 0x0;
3099 atio->sense_len = sizeof (atio->sense_data);
3100 }
3101 return_lun = CAM_LUN_WILDCARD;
3102 }
3103
3104 switch (cdb[0]) {
3105 case REQUEST_SENSE:
3106 flags |= CAM_DIR_IN;
3107 data_len = sizeof (atio->sense_data);
3108 junk_data[0] = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_NO_SENSE;
3109 memset(junk_data+1, 0, data_len-1);
3110 if (data_len > cdb[4]) {
3111 data_len = cdb[4];
3112 }
3113 if (data_len) {
3114 data_ptr = junk_data;
3115 }
3116 break;
3117 case READ_6:
3118 case READ_10:
3119 case READ_12:
3120 case READ_16:
3121 if (isptarg_rwparm(cdb, disk_data, disk_size, atio->ccb_h.ccb_data_offset, &data_ptr, &data_len, &last)) {
3122 status = SCSI_STATUS_CHECK_COND;
3123 atio->sense_data.error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_UNIT_ATTENTION;
3124 atio->sense_data.add_sense_code = 0x5;
3125 atio->sense_data.add_sense_code_qual = 0x24;
3126 atio->sense_len = sizeof (atio->sense_data);
3127 } else {
3128#ifdef ISP_FORCE_TIMEOUT
3129 {
3130 static int foo;
3131 if (foo++ == 500) {
3132 if (more) {
3133 xpt_schedule(periph, 1);
3134 }
3135 foo = 0;
3136 return;
3137 }
3138 }
3139#endif
3140#ifdef ISP_TEST_SEPARATE_STATUS
3141 if (last && data_len) {
3142 last = 0;
3143 }
3144#endif
3145 if (last == 0) {
3146 flags &= ~CAM_SEND_STATUS;
3147 }
3148 if (data_len) {
3149 atio->ccb_h.ccb_data_offset += data_len;
3150 flags |= CAM_DIR_IN;
3151 } else {
3152 flags |= CAM_DIR_NONE;
3153 }
3154 }
3155 break;
3156 case WRITE_6:
3157 case WRITE_10:
3158 case WRITE_12:
3159 case WRITE_16:
3160 if (isptarg_rwparm(cdb, disk_data, disk_size, atio->ccb_h.ccb_data_offset, &data_ptr, &data_len, &last)) {
3161 status = SCSI_STATUS_CHECK_COND;
3162 atio->sense_data.error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_UNIT_ATTENTION;
3163 atio->sense_data.add_sense_code = 0x5;
3164 atio->sense_data.add_sense_code_qual = 0x24;
3165 atio->sense_len = sizeof (atio->sense_data);
3166 } else {
3167#ifdef ISP_FORCE_TIMEOUT
3168 {
3169 static int foo;
3170 if (foo++ == 500) {
3171 if (more) {
3172 xpt_schedule(periph, 1);
3173 }
3174 foo = 0;
3175 return;
3176 }
3177 }
3178#endif
3179#ifdef ISP_TEST_SEPARATE_STATUS
3180 if (last && data_len) {
3181 last = 0;
3182 }
3183#endif
3184 if (last == 0) {
3185 flags &= ~CAM_SEND_STATUS;
3186 }
3187 if (data_len) {
3188 atio->ccb_h.ccb_data_offset += data_len;
3189 flags |= CAM_DIR_OUT;
3190 } else {
3191 flags |= CAM_DIR_NONE;
3192 }
3193 }
3194 break;
3195 case INQUIRY:
3196 flags |= CAM_DIR_IN;
3197 if (cdb[1] || cdb[2] || cdb[3]) {
3198 status = SCSI_STATUS_CHECK_COND;
3199 atio->sense_data.error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_UNIT_ATTENTION;
3200 atio->sense_data.add_sense_code = 0x5;
3201 atio->sense_data.add_sense_code_qual = 0x20;
3202 atio->sense_len = sizeof (atio->sense_data);
3203 break;
3204 }
3205 data_len = sizeof (iqd);
3206 if (data_len > cdb[4]) {
3207 data_len = cdb[4];
3208 }
3209 if (data_len) {
3210 if (XS_LUN(iccb) != 0) {
3211 memcpy(junk_data, niliqd, sizeof (iqd));
3212 } else {
3213 memcpy(junk_data, iqd, sizeof (iqd));
3214 }
3215 data_ptr = junk_data;
3216 }
3217 break;
3218 case TEST_UNIT_READY:
3219 flags |= CAM_DIR_NONE;
3220 if (ca) {
3221 ca = 0;
3222 status = SCSI_STATUS_CHECK_COND;
3223 atio->sense_data.error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_UNIT_ATTENTION;
3224 atio->sense_data.add_sense_code = 0x28;
3225 atio->sense_data.add_sense_code_qual = 0x0;
3226 atio->sense_len = sizeof (atio->sense_data);
3227 }
3228 break;
3229 case SYNCHRONIZE_CACHE:
3230 case START_STOP:
3231 case RESERVE:
3232 case RELEASE:
3233 case VERIFY_10:
3234 flags |= CAM_DIR_NONE;
3235 break;
3236
3237 case READ_CAPACITY:
3238 flags |= CAM_DIR_IN;
3239 if (cdb[2] || cdb[3] || cdb[4] || cdb[5]) {
3240 status = SCSI_STATUS_CHECK_COND;
3241 atio->sense_data.error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_UNIT_ATTENTION;
3242 atio->sense_data.add_sense_code = 0x5;
3243 atio->sense_data.add_sense_code_qual = 0x24;
3244 atio->sense_len = sizeof (atio->sense_data);
3245 break;
3246 }
3247 if (cdb[8] & 0x1) { /* PMI */
3248 junk_data[0] = 0xff;
3249 junk_data[1] = 0xff;
3250 junk_data[2] = 0xff;
3251 junk_data[3] = 0xff;
3252 } else {
3253 uint64_t last_blk = (disk_size >> DISK_SHIFT) - 1;
3254 if (last_blk < 0xffffffffULL) {
3255 junk_data[0] = (last_blk >> 24) & 0xff;
3256 junk_data[1] = (last_blk >> 16) & 0xff;
3257 junk_data[2] = (last_blk >> 8) & 0xff;
3258 junk_data[3] = (last_blk) & 0xff;
3259 } else {
3260 junk_data[0] = 0xff;
3261 junk_data[1] = 0xff;
3262 junk_data[2] = 0xff;
3263 junk_data[3] = 0xff;
3264 }
3265 }
3266 junk_data[4] = ((1 << DISK_SHIFT) >> 24) & 0xff;
3267 junk_data[5] = ((1 << DISK_SHIFT) >> 16) & 0xff;
3268 junk_data[6] = ((1 << DISK_SHIFT) >> 8) & 0xff;
3269 junk_data[7] = ((1 << DISK_SHIFT)) & 0xff;
3270 data_ptr = junk_data;
3271 data_len = 8;
3272 break;
3273 case REPORT_LUNS:
3274 flags |= CAM_DIR_IN;
3275 memset(junk_data, 0, JUNK_SIZE);
3276 junk_data[0] = (1 << 3) >> 24;
3277 junk_data[1] = (1 << 3) >> 16;
3278 junk_data[2] = (1 << 3) >> 8;
3279 junk_data[3] = (1 << 3);
3280 ptr = NULL;
3281 for (i = 0; i < 1; i++) {
3282 ptr = &junk_data[8 + (1 << 3)];
3283 if (i >= 256) {
3284 ptr[0] = 0x40 | ((i >> 8) & 0x3f);
3285 }
3286 ptr[1] = i;
3287 }
3288 data_ptr = junk_data;
3289 data_len = (ptr + 8) - junk_data;
3290 break;
3291
3292 default:
3293 flags |= CAM_DIR_NONE;
3294 status = SCSI_STATUS_CHECK_COND;
3295 atio->sense_data.error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_UNIT_ATTENTION;
3296 atio->sense_data.add_sense_code = 0x5;
3297 atio->sense_data.add_sense_code_qual = 0x20;
3298 atio->sense_len = sizeof (atio->sense_data);
3299 break;
3300 }
3301
3302 /*
3303 * If we are done with the transaction, tell the
3304 * controller to send status and perform a CMD_CMPLT.
3305 * If we have associated sense data, see if we can
3306 * send that too.
3307 */
3308 if (status == SCSI_STATUS_CHECK_COND) {
3309 flags |= CAM_SEND_SENSE;
3310 csio->sense_len = atio->sense_len;
3311 csio->sense_data = atio->sense_data;
3312 flags &= ~CAM_DIR_MASK;
3313 data_len = 0;
3314 data_ptr = NULL;
3315 }
3316 cam_fill_ctio(csio, 0, isptarg_done, flags, MSG_SIMPLE_Q_TAG, atio->tag_id, atio->init_id, status, data_ptr, data_len, 0);
3317 iccb->ccb_h.target_id = atio->ccb_h.target_id;
3318 iccb->ccb_h.target_lun = return_lun;
3319 iccb->ccb_h.ccb_atio = atio;
3320 xpt_action(iccb);
3321
3322 if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3323 cam_release_devq(periph->path, 0, 0, 0, 0);
3324 atio->ccb_h.status &= ~CAM_DEV_QFRZN;
3325 }
3326 if (more) {
3327 xpt_schedule(periph, 1);
3328 }
3329}
3330
3331static cam_status
3332isptargctor(struct cam_periph *periph, void *arg)
3333{
3334 struct isptarg_softc *softc;
3335
3336 softc = (struct isptarg_softc *)arg;
3337 periph->softc = softc;
3338 softc->periph = periph;
3339 softc->path = periph->path;
3340 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, periph->path, "%s called\n", __func__);
3341 return (CAM_REQ_CMP);
3342}
3343
3344static void
3345isptargdtor(struct cam_periph *periph)
3346{
3347 struct isptarg_softc *softc;
3348 softc = (struct isptarg_softc *)periph->softc;
3349 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, periph->path, "%s called\n", __func__);
3350 softc->periph = NULL;
3351 softc->path = NULL;
3352 periph->softc = NULL;
3353}
3354
3355static void
3356isptarg_done(struct cam_periph *periph, union ccb *ccb)
3357{
3358 struct isptarg_softc *softc;
3359 ispsoftc_t *isp;
3360 struct ccb_accept_tio *atio;
3361 struct ccb_immediate_notify *inot;
3362 cam_status status;
3363
3364 softc = (struct isptarg_softc *)periph->softc;
3365 isp = softc->isp;
3366 status = ccb->ccb_h.status & CAM_STATUS_MASK;
3367
3368 switch (ccb->ccb_h.func_code) {
3369 case XPT_ACCEPT_TARGET_IO:
3370 atio = (struct ccb_accept_tio *) ccb;
3371 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] ATIO seen in %s\n", atio->tag_id, __func__);
3372 TAILQ_INSERT_TAIL(&softc->work_queue, &ccb->ccb_h, periph_links.tqe);
3373 xpt_schedule(periph, 1);
3374 break;
3375 case XPT_IMMEDIATE_NOTIFY:
3376 inot = (struct ccb_immediate_notify *) ccb;
3377 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] INOT for 0x%x seen in %s\n", inot->tag_id, inot->seq_id, __func__);
3378 TAILQ_INSERT_TAIL(&softc->inot_queue, &ccb->ccb_h, periph_links.tqe);
3379 xpt_schedule(periph, 1);
3380 break;
3381 case XPT_CONT_TARGET_IO:
3382 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3383 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0);
3384 ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
3385 }
3386 atio = ccb->ccb_h.ccb_atio;
3387 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3388 cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL);
3389 xpt_action((union ccb *)atio);
3390 } else if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) {
3391 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] MID CTIO seen in %s\n", atio->tag_id, __func__);
3392 TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe);
3393 xpt_schedule(periph, 1);
3394 } else {
3395 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] FINAL CTIO seen in %s\n", atio->tag_id, __func__);
3396 xpt_action((union ccb *)atio);
3397 }
3398 xpt_release_ccb(ccb);
3399 break;
3400 case XPT_NOTIFY_ACKNOWLEDGE:
3401 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3402 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0);
3403 ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
3404 }
3405 inot = ccb->ccb_h.ccb_inot;
3406 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, inot->ccb_h.path, "[0x%x] recycle notify for tag 0x%x\n", inot->tag_id, inot->seq_id);
3407 xpt_release_ccb(ccb);
3408 xpt_action((union ccb *)inot);
3409 break;
3410 default:
3411 xpt_print(ccb->ccb_h.path, "unexpected code 0x%x\n", ccb->ccb_h.func_code);
3412 break;
3413 }
3414}
3415
3416static void
3417isptargasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
3418{
3419 struct ac_contract *acp = arg;
3420 struct ac_device_changed *fc = (struct ac_device_changed *) acp->contract_data;
3421
3422 if (code != AC_CONTRACT) {
3423 return;
3424 }
3425 xpt_print(path, "0x%016llx Port ID 0x%06x %s\n", (unsigned long long) fc->wwpn, fc->port, fc->arrived? "arrived" : "departed");
3426}
3427
3428static void
3429isp_target_thread(ispsoftc_t *isp, int chan)
3430{
3431 union ccb *ccb = NULL;
3432 int i;
3433 void *wchan;
3434 cam_status status;
3435 struct isptarg_softc *softc = NULL;
3436 struct cam_periph *periph = NULL, *wperiph = NULL;
3437 struct cam_path *path, *wpath;
3438 struct cam_sim *sim;
3439
3440 if (disk_data == NULL) {
3441 disk_size = roundup2(vm_kmem_size >> 1, (1ULL << 20));
3442 if (disk_size < (50 << 20)) {
3443 disk_size = 50 << 20;
3444 }
3445 disk_data = malloc(disk_size, M_ISPTARG, M_WAITOK | M_ZERO);
3446 if (disk_data == NULL) {
3447 isp_prt(isp, ISP_LOGERR, "%s: could not allocate disk data", __func__);
3448 goto out;
3449 }
3450 isp_prt(isp, ISP_LOGINFO, "allocated a %ju MiB disk", (uintmax_t) (disk_size >> 20));
3451 }
3452 junk_data = malloc(JUNK_SIZE, M_ISPTARG, M_WAITOK | M_ZERO);
3453 if (junk_data == NULL) {
3454 isp_prt(isp, ISP_LOGERR, "%s: could not allocate junk", __func__);
3455 goto out;
3456 }
3457
3458
3459 softc = malloc(sizeof (*softc), M_ISPTARG, M_WAITOK | M_ZERO);
3460 if (softc == NULL) {
3461 isp_prt(isp, ISP_LOGERR, "%s: could not allocate softc", __func__);
3462 goto out;
3463 }
3464 TAILQ_INIT(&softc->work_queue);
3465 TAILQ_INIT(&softc->rework_queue);
3466 TAILQ_INIT(&softc->running_queue);
3467 TAILQ_INIT(&softc->inot_queue);
3468 softc->isp = isp;
3469
3470 periphdriver_register(&isptargdriver);
3471 ISP_GET_PC(isp, chan, sim, sim);
3472 ISP_GET_PC(isp, chan, path, path);
3473 status = xpt_create_path_unlocked(&wpath, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
3474 if (status != CAM_REQ_CMP) {
3475 isp_prt(isp, ISP_LOGERR, "%s: could not allocate wildcard path", __func__);
3476 return;
3477 }
3478 status = xpt_create_path_unlocked(&path, NULL, cam_sim_path(sim), 0, 0);
3479 if (status != CAM_REQ_CMP) {
3480 xpt_free_path(wpath);
3481 isp_prt(isp, ISP_LOGERR, "%s: could not allocate path", __func__);
3482 return;
3483 }
3484
3485 ccb = xpt_alloc_ccb();
3486
3487 ISP_LOCK(isp);
3488 status = cam_periph_alloc(isptargctor, NULL, isptargdtor, isptargstart, "isptarg", CAM_PERIPH_BIO, wpath, NULL, 0, softc);
3489 if (status != CAM_REQ_CMP) {
3490 ISP_UNLOCK(isp);
3491 isp_prt(isp, ISP_LOGERR, "%s: cam_periph_alloc for wildcard failed", __func__);
3492 goto out;
3493 }
3494 wperiph = cam_periph_find(wpath, "isptarg");
3495 if (wperiph == NULL) {
3496 ISP_UNLOCK(isp);
3497 isp_prt(isp, ISP_LOGERR, "%s: wildcard periph already allocated but doesn't exist", __func__);
3498 goto out;
3499 }
3500
3501 status = cam_periph_alloc(isptargctor, NULL, isptargdtor, isptargstart, "isptarg", CAM_PERIPH_BIO, path, NULL, 0, softc);
3502 if (status != CAM_REQ_CMP) {
3503 ISP_UNLOCK(isp);
3504 isp_prt(isp, ISP_LOGERR, "%s: cam_periph_alloc failed", __func__);
3505 goto out;
3506 }
3507
3508 periph = cam_periph_find(path, "isptarg");
3509 if (periph == NULL) {
3510 ISP_UNLOCK(isp);
3511 isp_prt(isp, ISP_LOGERR, "%s: periph already allocated but doesn't exist", __func__);
3512 goto out;
3513 }
3514
3515 status = xpt_register_async(AC_CONTRACT, isptargasync, isp, wpath);
3516 if (status != CAM_REQ_CMP) {
3517 ISP_UNLOCK(isp);
3518 isp_prt(isp, ISP_LOGERR, "%s: xpt_register_async failed", __func__);
3519 goto out;
3520 }
3521
3522 ISP_UNLOCK(isp);
3523
3524 ccb = xpt_alloc_ccb();
3525
3526 /*
3527 * Make sure role is none.
3528 */
3529 xpt_setup_ccb(&ccb->ccb_h, periph->path, 10);
3530 ccb->ccb_h.func_code = XPT_SET_SIM_KNOB;
3531 ccb->knob.xport_specific.fc.role = KNOB_ROLE_NONE;
3532#ifdef ISP_TEST_WWNS
3533 ccb->knob.xport_specific.fc.valid = KNOB_VALID_ROLE | KNOB_VALID_ADDRESS;
3534 ccb->knob.xport_specific.fc.wwnn = 0x508004d000000000ULL | (device_get_unit(isp->isp_osinfo.dev) << 8) | (chan << 16);
3535 ccb->knob.xport_specific.fc.wwpn = 0x508004d000000001ULL | (device_get_unit(isp->isp_osinfo.dev) << 8) | (chan << 16);
3536#else
3537 ccb->knob.xport_specific.fc.valid = KNOB_VALID_ROLE;
3538#endif
3539
3540 ISP_LOCK(isp);
3541 xpt_action(ccb);
3542 ISP_UNLOCK(isp);
3543
3544 /*
3545 * Now enable luns
3546 */
3547 xpt_setup_ccb(&ccb->ccb_h, periph->path, 10);
3548 ccb->ccb_h.func_code = XPT_EN_LUN;
3549 ccb->cel.enable = 1;
3550 ISP_LOCK(isp);
3551 xpt_action(ccb);
3552 ISP_UNLOCK(isp);
3553 if (ccb->ccb_h.status != CAM_REQ_CMP) {
3554 xpt_free_ccb(ccb);
3555 xpt_print(periph->path, "failed to enable lun (0x%x)\n", ccb->ccb_h.status);
3556 goto out;
3557 }
3558
3559 xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 10);
3560 ccb->ccb_h.func_code = XPT_EN_LUN;
3561 ccb->cel.enable = 1;
3562 ISP_LOCK(isp);
3563 xpt_action(ccb);
3564 ISP_UNLOCK(isp);
3565 if (ccb->ccb_h.status != CAM_REQ_CMP) {
3566 xpt_free_ccb(ccb);
3567 xpt_print(wperiph->path, "failed to enable lun (0x%x)\n", ccb->ccb_h.status);
3568 goto out;
3569 }
3570 xpt_free_ccb(ccb);
3571
3572 /*
3573 * Add resources
3574 */
3575 ISP_GET_PC_ADDR(isp, chan, target_proc, wchan);
3576 for (i = 0; i < 4; i++) {
3577 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO);
3578 xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 1);
3579 ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
3580 ccb->ccb_h.cbfcnp = isptarg_done;
3581 ISP_LOCK(isp);
3582 xpt_action(ccb);
3583 ISP_UNLOCK(isp);
3584 }
3585 for (i = 0; i < NISP_TARG_CMDS; i++) {
3586 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO);
3587 xpt_setup_ccb(&ccb->ccb_h, periph->path, 1);
3588 ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
3589 ccb->ccb_h.cbfcnp = isptarg_done;
3590 ISP_LOCK(isp);
3591 xpt_action(ccb);
3592 ISP_UNLOCK(isp);
3593 }
3594 for (i = 0; i < 4; i++) {
3595 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO);
3596 xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 1);
3597 ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
3598 ccb->ccb_h.cbfcnp = isptarg_done;
3599 ISP_LOCK(isp);
3600 xpt_action(ccb);
3601 ISP_UNLOCK(isp);
3602 }
3603 for (i = 0; i < NISP_TARG_NOTIFIES; i++) {
3604 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO);
3605 xpt_setup_ccb(&ccb->ccb_h, periph->path, 1);
3606 ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
3607 ccb->ccb_h.cbfcnp = isptarg_done;
3608 ISP_LOCK(isp);
3609 xpt_action(ccb);
3610 ISP_UNLOCK(isp);
3611 }
3612
3613 /*
3614 * Now turn it all back on
3615 */
3616 xpt_setup_ccb(&ccb->ccb_h, periph->path, 10);
3617 ccb->ccb_h.func_code = XPT_SET_SIM_KNOB;
3618 ccb->knob.xport_specific.fc.valid = KNOB_VALID_ROLE;
3619 ccb->knob.xport_specific.fc.role = KNOB_ROLE_TARGET;
3620 ISP_LOCK(isp);
3621 xpt_action(ccb);
3622 ISP_UNLOCK(isp);
3623
3624 /*
3625 * Okay, while things are still active, sleep...
3626 */
3627 ISP_LOCK(isp);
3628 for (;;) {
3629 ISP_GET_PC(isp, chan, proc_active, i);
3630 if (i == 0) {
3631 break;
3632 }
3633 msleep(wchan, &isp->isp_lock, PUSER, "tsnooze", 0);
3634 }
3635 ISP_UNLOCK(isp);
3636
3637out:
3638 if (wperiph) {
3639 cam_periph_invalidate(wperiph);
3640 }
3641 if (periph) {
3642 cam_periph_invalidate(periph);
3643 }
3644 if (junk_data) {
3645 free(junk_data, M_ISPTARG);
3646 }
3647 if (disk_data) {
3648 free(disk_data, M_ISPTARG);
3649 }
3650 if (softc) {
3651 free(softc, M_ISPTARG);
3652 }
3653 xpt_free_path(path);
3654 xpt_free_path(wpath);
3655}
3656
3657static void
3658isp_target_thread_pi(void *arg)
3659{
3660 struct isp_spi *pi = arg;
3661 isp_target_thread(cam_sim_softc(pi->sim), cam_sim_bus(pi->sim));
3662}
3663
3664static void
3665isp_target_thread_fc(void *arg)
3666{
3667 struct isp_fc *fc = arg;
3668 isp_target_thread(cam_sim_softc(fc->sim), cam_sim_bus(fc->sim));
3669}
3670
3671static int
3672isptarg_rwparm(uint8_t *cdb, uint8_t *dp, uint64_t dl, uint32_t offset, uint8_t **kp, uint32_t *tl, int *lp)
3673{
3674 uint32_t cnt, curcnt;
3675 uint64_t lba;
3676
3677 switch (cdb[0]) {
3678 case WRITE_16:
3679 case READ_16:
3680 cnt = (((uint32_t)cdb[10]) << 24) |
3681 (((uint32_t)cdb[11]) << 16) |
3682 (((uint32_t)cdb[12]) << 8) |
3683 ((uint32_t)cdb[13]);
3684
3685 lba = (((uint64_t)cdb[2]) << 56) |
3686 (((uint64_t)cdb[3]) << 48) |
3687 (((uint64_t)cdb[4]) << 40) |
3688 (((uint64_t)cdb[5]) << 32) |
3689 (((uint64_t)cdb[6]) << 24) |
3690 (((uint64_t)cdb[7]) << 16) |
3691 (((uint64_t)cdb[8]) << 8) |
3692 ((uint64_t)cdb[9]);
3693 break;
3694 case WRITE_12:
3695 case READ_12:
3696 cnt = (((uint32_t)cdb[6]) << 16) |
3697 (((uint32_t)cdb[7]) << 8) |
3698 ((u_int32_t)cdb[8]);
3699
3700 lba = (((uint32_t)cdb[2]) << 24) |
3701 (((uint32_t)cdb[3]) << 16) |
3702 (((uint32_t)cdb[4]) << 8) |
3703 ((uint32_t)cdb[5]);
3704 break;
3705 case WRITE_10:
3706 case READ_10:
3707 cnt = (((uint32_t)cdb[7]) << 8) |
3708 ((u_int32_t)cdb[8]);
3709
3710 lba = (((uint32_t)cdb[2]) << 24) |
3711 (((uint32_t)cdb[3]) << 16) |
3712 (((uint32_t)cdb[4]) << 8) |
3713 ((uint32_t)cdb[5]);
3714 break;
3715 case WRITE_6:
3716 case READ_6:
3717 cnt = cdb[4];
3718 if (cnt == 0) {
3719 cnt = 256;
3720 }
3721 lba = (((uint32_t)cdb[1] & 0x1f) << 16) |
3722 (((uint32_t)cdb[2]) << 8) |
3723 ((uint32_t)cdb[3]);
3724 break;
3725 default:
3726 return (-1);
3727 }
3728
3729 cnt <<= DISK_SHIFT;
3730 lba <<= DISK_SHIFT;
3731
3732 if (offset == cnt) {
3733 *lp = 1;
3734 return (0);
3735 }
3736
3737 if (lba + cnt > dl) {
3738 return (-1);
3739 }
3740
3741
3742 curcnt = MAX_ISP_TARG_TRANSFER;
3743 if (offset + curcnt >= cnt) {
3744 curcnt = cnt - offset;
3745 *lp = 1;
3746 } else {
3747 *lp = 0;
3748 }
3749 *tl = curcnt;
3750 *kp = &dp[lba + offset];
3751 return (0);
3752}
3753
3754#endif
3755#endif
3756
3757static void
1877isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
1878{
1879 struct cam_sim *sim;
1880 ispsoftc_t *isp;
1881
1882 sim = (struct cam_sim *)cbarg;
1883 isp = (ispsoftc_t *) cam_sim_softc(sim);
1884 switch (code) {
1885 case AC_LOST_DEVICE:
1886 if (IS_SCSI(isp)) {
1887 uint16_t oflags, nflags;
3758isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
3759{
3760 struct cam_sim *sim;
3761 ispsoftc_t *isp;
3762
3763 sim = (struct cam_sim *)cbarg;
3764 isp = (ispsoftc_t *) cam_sim_softc(sim);
3765 switch (code) {
3766 case AC_LOST_DEVICE:
3767 if (IS_SCSI(isp)) {
3768 uint16_t oflags, nflags;
1888 sdparam *sdp = isp->isp_param;
3769 int bus = cam_sim_bus(sim);
3770 sdparam *sdp = SDPARAM(isp, bus);
1889 int tgt;
1890
1891 tgt = xpt_path_target_id(path);
1892 if (tgt >= 0) {
3771 int tgt;
3772
3773 tgt = xpt_path_target_id(path);
3774 if (tgt >= 0) {
1893 sdp += cam_sim_bus(sim);
1894 nflags = sdp->isp_devparam[tgt].nvrm_flags;
1895#ifndef ISP_TARGET_MODE
1896 nflags &= DPARM_SAFE_DFLT;
1897 if (isp->isp_loaded_fw) {
1898 nflags |= DPARM_NARROW | DPARM_ASYNC;
1899 }
1900#else
1901 nflags = DPARM_DEFAULT;
1902#endif
1903 oflags = sdp->isp_devparam[tgt].goal_flags;
1904 sdp->isp_devparam[tgt].goal_flags = nflags;
1905 sdp->isp_devparam[tgt].dev_update = 1;
3775 nflags = sdp->isp_devparam[tgt].nvrm_flags;
3776#ifndef ISP_TARGET_MODE
3777 nflags &= DPARM_SAFE_DFLT;
3778 if (isp->isp_loaded_fw) {
3779 nflags |= DPARM_NARROW | DPARM_ASYNC;
3780 }
3781#else
3782 nflags = DPARM_DEFAULT;
3783#endif
3784 oflags = sdp->isp_devparam[tgt].goal_flags;
3785 sdp->isp_devparam[tgt].goal_flags = nflags;
3786 sdp->isp_devparam[tgt].dev_update = 1;
1906 isp->isp_update |= (1 << cam_sim_bus(sim));
1907 (void) isp_control(isp,
1908 ISPCTL_UPDATE_PARAMS, NULL);
3787 sdp->update = 1;
3788 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus);
1909 sdp->isp_devparam[tgt].goal_flags = oflags;
1910 }
1911 }
1912 break;
1913 default:
1914 isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code);
1915 break;
1916 }

--- 7 unchanged lines hidden (view full) ---

1924 uint16_t sema, mbox;
1925
1926 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
1927 isp_intr(isp, isr, sema, mbox);
1928 }
1929}
1930
1931
3789 sdp->isp_devparam[tgt].goal_flags = oflags;
3790 }
3791 }
3792 break;
3793 default:
3794 isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code);
3795 break;
3796 }

--- 7 unchanged lines hidden (view full) ---

3804 uint16_t sema, mbox;
3805
3806 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
3807 isp_intr(isp, isr, sema, mbox);
3808 }
3809}
3810
3811
1932static int isp_watchdog_work(ispsoftc_t *, XS_T *);
1933
1934static int
1935isp_watchdog_work(ispsoftc_t *isp, XS_T *xs)
3812static void
3813isp_watchdog(void *arg)
1936{
3814{
3815 struct ccb_scsiio *xs = arg;
3816 ispsoftc_t *isp;
1937 uint32_t handle;
1938
3817 uint32_t handle;
3818
1939 /*
1940 * We've decided this command is dead. Make sure we're not trying
1941 * to kill a command that's already dead by getting it's handle and
1942 * and seeing whether it's still alive.
1943 */
3819 isp = XS_ISP(xs);
3820
1944 handle = isp_find_handle(isp, xs);
1945 if (handle) {
3821 handle = isp_find_handle(isp, xs);
3822 if (handle) {
1946 uint32_t isr;
1947 uint16_t sema, mbox;
3823 /*
3824 * Make sure the command is *really* dead before we
3825 * release the handle (and DMA resources) for reuse.
3826 */
3827 (void) isp_control(isp, ISPCTL_ABORT_CMD, xs);
1948
3828
1949 if (XS_CMD_DONE_P(xs)) {
1950 isp_prt(isp, ISP_LOGDEBUG1,
1951 "watchdog found done cmd (handle 0x%x)", handle);
1952 return (1);;
1953 }
1954
1955 if (XS_CMD_WDOG_P(xs)) {
1956 isp_prt(isp, ISP_LOGDEBUG2,
1957 "recursive watchdog (handle 0x%x)", handle);
1958 return (1);
1959 }
1960
1961 XS_CMD_S_WDOG(xs);
1962 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
1963 isp_intr(isp, isr, sema, mbox);
1964 }
1965 if (XS_CMD_DONE_P(xs)) {
1966 isp_prt(isp, ISP_LOGDEBUG2,
1967 "watchdog cleanup for handle 0x%x", handle);
1968 isp_free_pcmd(isp, (union ccb *)xs);
1969 xpt_done((union ccb *) xs);
1970 } else if (XS_CMD_GRACE_P(xs)) {
1971 /*
1972 * Make sure the command is *really* dead before we
1973 * release the handle (and DMA resources) for reuse.
1974 */
1975 (void) isp_control(isp, ISPCTL_ABORT_CMD, xs);
1976
1977 /*
1978 * After this point, the comamnd is really dead.
1979 */
1980 if (XS_XFRLEN(xs)) {
1981 ISP_DMAFREE(isp, xs, handle);
1982 }
1983 isp_destroy_handle(isp, handle);
1984 xpt_print(xs->ccb_h.path,
1985 "watchdog timeout for handle 0x%x\n", handle);
1986 XS_SETERR(xs, CAM_CMD_TIMEOUT);
1987 XS_CMD_C_WDOG(xs);
1988 isp_done(xs);
1989 } else {
1990 XS_CMD_C_WDOG(xs);
1991 callout_reset(&PISP_PCMD((union ccb *)xs)->wdog, hz,
1992 isp_watchdog, xs);
1993 XS_CMD_S_GRACE(xs);
1994 isp->isp_sendmarker |= 1 << XS_CHANNEL(xs);
1995 }
1996 return (1);
3829 /*
3830 * After this point, the comamnd is really dead.
3831 */
3832 if (XS_XFRLEN(xs)) {
3833 ISP_DMAFREE(isp, xs, handle);
3834 }
3835 isp_destroy_handle(isp, handle);
3836 xpt_print(xs->ccb_h.path, "watchdog timeout for handle 0x%x\n", handle);
3837 XS_SETERR(xs, CAM_CMD_TIMEOUT);
3838 isp_done(xs);
1997 }
3839 }
1998 return (0);
1999}
2000
2001static void
3840}
3841
3842static void
2002isp_watchdog(void *arg)
3843isp_make_here(ispsoftc_t *isp, int chan, int tgt)
2003{
3844{
2004 ispsoftc_t *isp;
2005 XS_T *xs = arg;
2006 int r;
3845 union ccb *ccb;
3846 struct isp_fc *fc = ISP_FC_PC(isp, chan);
2007
3847
2008 for (r = 0, isp = isplist; r && isp; isp = isp->isp_osinfo.next) {
2009 ISP_LOCK(isp);
2010 r = isp_watchdog_work(isp, xs);
2011 ISP_UNLOCK(isp);
3848 if (isp_autoconfig == 0) {
3849 return;
2012 }
3850 }
2013 if (isp == NULL) {
2014 printf("isp_watchdog: nobody had %p active\n", arg);
2015 }
2016}
2017
3851
2018
2019#if __FreeBSD_version >= 600000
2020static void
2021isp_make_here(ispsoftc_t *isp, int tgt)
2022{
2023 union ccb *ccb;
2024 /*
3852 /*
2025 * Allocate a CCB, create a wildcard path for this bus,
2026 * and schedule a rescan.
3853 * Allocate a CCB, create a wildcard path for this bus/target and schedule a rescan.
2027 */
2028 ccb = xpt_alloc_ccb_nowait();
2029 if (ccb == NULL) {
3854 */
3855 ccb = xpt_alloc_ccb_nowait();
3856 if (ccb == NULL) {
2030 isp_prt(isp, ISP_LOGWARN, "unable to alloc CCB for rescan");
3857 isp_prt(isp, ISP_LOGWARN, "Chan %d unable to alloc CCB for rescan", chan);
2031 return;
2032 }
3858 return;
3859 }
2033 if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
2034 cam_sim_path(isp->isp_sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
3860 if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2035 isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
2036 xpt_free_ccb(ccb);
2037 return;
2038 }
2039 xpt_rescan(ccb);
2040}
2041
2042static void
3861 isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
3862 xpt_free_ccb(ccb);
3863 return;
3864 }
3865 xpt_rescan(ccb);
3866}
3867
3868static void
2043isp_make_gone(ispsoftc_t *isp, int tgt)
3869isp_make_gone(ispsoftc_t *isp, int chan, int tgt)
2044{
2045 struct cam_path *tp;
3870{
3871 struct cam_path *tp;
2046 if (xpt_create_path(&tp, NULL, cam_sim_path(isp->isp_sim), tgt,
2047 CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
3872 struct isp_fc *fc = ISP_FC_PC(isp, chan);
3873
3874 if (isp_autoconfig == 0) {
3875 return;
3876 }
3877 if (xpt_create_path(&tp, NULL, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
2048 xpt_async(AC_LOST_DEVICE, tp, NULL);
2049 xpt_free_path(tp);
2050 }
2051}
3878 xpt_async(AC_LOST_DEVICE, tp, NULL);
3879 xpt_free_path(tp);
3880 }
3881}
2052#else
2053#define isp_make_here(isp, tgt) do { ; } while (0)
2054#define isp_make_gone(isp, tgt) do { ; } while (0)
2055#endif
2056
3882
2057
2058/*
2059 * Gone Device Timer Function- when we have decided that a device has gone
2060 * away, we wait a specific period of time prior to telling the OS it has
2061 * gone away.
2062 *
2063 * This timer function fires once a second and then scans the port database
2064 * for devices that are marked dead but still have a virtual target assigned.
2065 * We decrement a counter for that port database entry, and when it hits zero,
2066 * we tell the OS the device has gone away.
2067 */
2068static void
2069isp_gdt(void *arg)
2070{
3883/*
3884 * Gone Device Timer Function- when we have decided that a device has gone
3885 * away, we wait a specific period of time prior to telling the OS it has
3886 * gone away.
3887 *
3888 * This timer function fires once a second and then scans the port database
3889 * for devices that are marked dead but still have a virtual target assigned.
3890 * We decrement a counter for that port database entry, and when it hits zero,
3891 * we tell the OS the device has gone away.
3892 */
3893static void
3894isp_gdt(void *arg)
3895{
2071 ispsoftc_t *isp = arg;
3896 struct isp_fc *fc = arg;
3897 ispsoftc_t *isp = fc->isp;
3898 int chan = fc - isp->isp_osinfo.pc.fc;
2072 fcportdb_t *lp;
2073 int dbidx, tgt, more_to_do = 0;
2074
3899 fcportdb_t *lp;
3900 int dbidx, tgt, more_to_do = 0;
3901
2075 ISP_LOCK(isp);
2076 isp_prt(isp, ISP_LOGDEBUG0, "GDT timer expired");
3902 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GDT timer expired", chan);
2077 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3903 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2078 lp = &FCPARAM(isp)->portdb[dbidx];
3904 lp = &FCPARAM(isp, chan)->portdb[dbidx];
2079
2080 if (lp->state != FC_PORTDB_STATE_ZOMBIE) {
2081 continue;
2082 }
3905
3906 if (lp->state != FC_PORTDB_STATE_ZOMBIE) {
3907 continue;
3908 }
2083 if (lp->ini_map_idx == 0) {
3909 if (lp->dev_map_idx == 0 || lp->target_mode) {
2084 continue;
2085 }
2086 if (lp->new_reserved == 0) {
2087 continue;
2088 }
2089 lp->new_reserved -= 1;
2090 if (lp->new_reserved != 0) {
2091 more_to_do++;
2092 continue;
2093 }
3910 continue;
3911 }
3912 if (lp->new_reserved == 0) {
3913 continue;
3914 }
3915 lp->new_reserved -= 1;
3916 if (lp->new_reserved != 0) {
3917 more_to_do++;
3918 continue;
3919 }
2094 tgt = lp->ini_map_idx - 1;
2095 FCPARAM(isp)->isp_ini_map[tgt] = 0;
2096 lp->ini_map_idx = 0;
3920 tgt = lp->dev_map_idx - 1;
3921 FCPARAM(isp, chan)->isp_dev_map[tgt] = 0;
3922 lp->dev_map_idx = 0;
2097 lp->state = FC_PORTDB_STATE_NIL;
3923 lp->state = FC_PORTDB_STATE_NIL;
2098 isp_prt(isp, ISP_LOGCONFIG, prom3, lp->portid, tgt,
2099 "Gone Device Timeout");
2100 isp_make_gone(isp, tgt);
3924 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, tgt, "Gone Device Timeout");
3925 isp_make_gone(isp, chan, tgt);
2101 }
2102 if (more_to_do) {
3926 }
3927 if (more_to_do) {
2103 isp->isp_osinfo.gdt_running = 1;
2104 callout_reset(&isp->isp_osinfo.gdt, hz, isp_gdt, isp);
3928 fc->gdt_running = 1;
3929 callout_reset(&fc->gdt, hz, isp_gdt, fc);
2105 } else {
3930 } else {
2106 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2107 "stopping Gone Device Timer");
2108 isp->isp_osinfo.gdt_running = 0;
3931 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d stopping Gone Device Timer", chan);
3932 fc->gdt_running = 0;
2109 }
3933 }
2110 ISP_UNLOCK(isp);
2111}
2112
2113/*
2114 * Loop Down Timer Function- when loop goes down, a timer is started and
2115 * and after it expires we come here and take all probational devices that
2116 * the OS knows about and the tell the OS that they've gone away.
2117 *
2118 * We don't clear the devices out of our port database because, when loop
2119 * come back up, we have to do some actual cleanup with the chip at that
2120 * point (implicit PLOGO, e.g., to get the chip's port database state right).
2121 */
2122static void
2123isp_ldt(void *arg)
2124{
3934}
3935
3936/*
3937 * Loop Down Timer Function- when loop goes down, a timer is started and
3938 * and after it expires we come here and take all probational devices that
3939 * the OS knows about and the tell the OS that they've gone away.
3940 *
3941 * We don't clear the devices out of our port database because, when loop
3942 * come back up, we have to do some actual cleanup with the chip at that
3943 * point (implicit PLOGO, e.g., to get the chip's port database state right).
3944 */
3945static void
3946isp_ldt(void *arg)
3947{
2125 ispsoftc_t *isp = arg;
3948 struct isp_fc *fc = arg;
3949 ispsoftc_t *isp = fc->isp;
3950 int chan = fc - isp->isp_osinfo.pc.fc;
2126 fcportdb_t *lp;
2127 int dbidx, tgt;
2128
3951 fcportdb_t *lp;
3952 int dbidx, tgt;
3953
2129 ISP_LOCK(isp);
3954 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d Loop Down Timer expired @ %lu", chan, (unsigned long) time_uptime);
2130
3955
2131 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Loop Down Timer expired");
2132
2133 /*
2134 * Notify to the OS all targets who we now consider have departed.
2135 */
2136 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3956 /*
3957 * Notify to the OS all targets who we now consider have departed.
3958 */
3959 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2137 lp = &FCPARAM(isp)->portdb[dbidx];
3960 lp = &FCPARAM(isp, chan)->portdb[dbidx];
2138
2139 if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
2140 continue;
2141 }
3961
3962 if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
3963 continue;
3964 }
2142 if (lp->ini_map_idx == 0) {
3965 if (lp->dev_map_idx == 0 || lp->target_mode) {
2143 continue;
2144 }
2145
2146 /*
2147 * XXX: CLEAN UP AND COMPLETE ANY PENDING COMMANDS FIRST!
2148 */
2149
2150 /*
2151 * Mark that we've announced that this device is gone....
2152 */
2153 lp->reserved = 1;
2154
2155 /*
2156 * but *don't* change the state of the entry. Just clear
2157 * any target id stuff and announce to CAM that the
2158 * device is gone. This way any necessary PLOGO stuff
2159 * will happen when loop comes back up.
2160 */
2161
3966 continue;
3967 }
3968
3969 /*
3970 * XXX: CLEAN UP AND COMPLETE ANY PENDING COMMANDS FIRST!
3971 */
3972
3973 /*
3974 * Mark that we've announced that this device is gone....
3975 */
3976 lp->reserved = 1;
3977
3978 /*
3979 * but *don't* change the state of the entry. Just clear
3980 * any target id stuff and announce to CAM that the
3981 * device is gone. This way any necessary PLOGO stuff
3982 * will happen when loop comes back up.
3983 */
3984
2162 tgt = lp->ini_map_idx - 1;
2163 FCPARAM(isp)->isp_ini_map[tgt] = 0;
2164 lp->ini_map_idx = 0;
2165 isp_prt(isp, ISP_LOGCONFIG, prom3, lp->portid, tgt,
2166 "Loop Down Timeout");
2167 isp_make_gone(isp, tgt);
3985 tgt = lp->dev_map_idx - 1;
3986 FCPARAM(isp, chan)->isp_dev_map[tgt] = 0;
3987 lp->dev_map_idx = 0;
3988 lp->state = FC_PORTDB_STATE_NIL;
3989 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, tgt, "Loop Down Timeout");
3990 isp_make_gone(isp, chan, tgt);
2168 }
2169
2170 /*
2171 * The loop down timer has expired. Wake up the kthread
2172 * to notice that fact (or make it false).
2173 */
3991 }
3992
3993 /*
3994 * The loop down timer has expired. Wake up the kthread
3995 * to notice that fact (or make it false).
3996 */
2174 isp->isp_osinfo.loop_down_time = isp->isp_osinfo.loop_down_limit+1;
2175 wakeup(ISP_KT_WCHAN(isp));
2176 ISP_UNLOCK(isp);
3997 fc->loop_dead = 1;
3998 fc->loop_down_time = fc->loop_down_limit+1;
3999 wakeup(fc);
2177}
2178
2179static void
2180isp_kthread(void *arg)
2181{
4000}
4001
4002static void
4003isp_kthread(void *arg)
4004{
2182 ispsoftc_t *isp = arg;
4005 struct isp_fc *fc = arg;
4006 ispsoftc_t *isp = fc->isp;
4007 int chan = fc - isp->isp_osinfo.pc.fc;
2183 int slp = 0;
4008 int slp = 0;
2184#if __FreeBSD_version < 500000
2185 int s = splcam();
2186#elif __FreeBSD_version < 700037
2187 mtx_lock(&Giant);
2188#else
2189 mtx_lock(&isp->isp_osinfo.lock);
4009 mtx_lock(&isp->isp_osinfo.lock);
2190#endif
2191 /*
2192 * The first loop is for our usage where we have yet to have
2193 * gotten good fibre channel state.
2194 */
4010
2195 for (;;) {
2196 int wasfrozen, lb, lim;
2197
4011 for (;;) {
4012 int wasfrozen, lb, lim;
4013
2198 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2199 "isp_kthread: checking FC state");
2200 isp->isp_osinfo.mbox_sleep_ok = 1;
2201 lb = isp_fc_runstate(isp, 250000);
2202 isp->isp_osinfo.mbox_sleep_ok = 0;
2203 if (lb) {
4014 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "%s: Chan %d checking FC state", __func__, chan);
4015 lb = isp_fc_runstate(isp, chan, 250000);
4016
4017 /*
4018 * Our action is different based upon whether we're supporting
4019 * Initiator mode or not. If we are, we might freeze the simq
4020 * when loop is down and set all sorts of different delays to
4021 * check again.
4022 *
4023 * If not, we simply just wait for loop to come up.
4024 */
4025 if (lb && (fc->role & ISP_ROLE_INITIATOR)) {
2204 /*
2205 * Increment loop down time by the last sleep interval
2206 */
4026 /*
4027 * Increment loop down time by the last sleep interval
4028 */
2207 isp->isp_osinfo.loop_down_time += slp;
4029 fc->loop_down_time += slp;
2208
2209 if (lb < 0) {
4030
4031 if (lb < 0) {
2210 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2211 "kthread: FC loop not up (down count %d)",
2212 isp->isp_osinfo.loop_down_time);
4032 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC loop not up (down count %d)", __func__, chan, fc->loop_down_time);
2213 } else {
4033 } else {
2214 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2215 "kthread: FC got to %d (down count %d)",
2216 lb, isp->isp_osinfo.loop_down_time);
4034 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC got to %d (down count %d)", __func__, chan, lb, fc->loop_down_time);
2217 }
2218
4035 }
4036
2219
2220 /*
2221 * If we've never seen loop up and we've waited longer
2222 * than quickboot time, or we've seen loop up but we've
2223 * waited longer than loop_down_limit, give up and go
2224 * to sleep until loop comes up.
2225 */
4037 /*
4038 * If we've never seen loop up and we've waited longer
4039 * than quickboot time, or we've seen loop up but we've
4040 * waited longer than loop_down_limit, give up and go
4041 * to sleep until loop comes up.
4042 */
2226 if (FCPARAM(isp)->loop_seen_once == 0) {
4043 if (FCPARAM(isp, chan)->loop_seen_once == 0) {
2227 lim = isp_quickboot_time;
2228 } else {
4044 lim = isp_quickboot_time;
4045 } else {
2229 lim = isp->isp_osinfo.loop_down_limit;
4046 lim = fc->loop_down_limit;
2230 }
4047 }
2231 if (isp->isp_osinfo.loop_down_time >= lim) {
2232 isp_freeze_loopdown(isp, "loop limit hit");
4048 if (fc->loop_down_time >= lim) {
4049 isp_freeze_loopdown(isp, chan, "loop limit hit");
2233 slp = 0;
4050 slp = 0;
2234 } else if (isp->isp_osinfo.loop_down_time < 10) {
4051 } else if (fc->loop_down_time < 10) {
2235 slp = 1;
4052 slp = 1;
2236 } else if (isp->isp_osinfo.loop_down_time < 30) {
4053 } else if (fc->loop_down_time < 30) {
2237 slp = 5;
4054 slp = 5;
2238 } else if (isp->isp_osinfo.loop_down_time < 60) {
4055 } else if (fc->loop_down_time < 60) {
2239 slp = 10;
4056 slp = 10;
2240 } else if (isp->isp_osinfo.loop_down_time < 120) {
4057 } else if (fc->loop_down_time < 120) {
2241 slp = 20;
2242 } else {
2243 slp = 30;
2244 }
2245
4058 slp = 20;
4059 } else {
4060 slp = 30;
4061 }
4062
4063 } else if (lb) {
4064 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC Loop Down", __func__, chan);
4065 fc->loop_down_time += slp;
4066 slp = 60;
2246 } else {
4067 } else {
2247 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2248 "isp_kthread: FC state OK");
2249 isp->isp_osinfo.loop_down_time = 0;
4068 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC state OK", __func__, chan);
4069 fc->loop_down_time = 0;
2250 slp = 0;
2251 }
2252
4070 slp = 0;
4071 }
4072
4073
2253 /*
4074 /*
2254 * If we'd frozen the simq, unfreeze it now so that CAM
2255 * can start sending us commands. If the FC state isn't
2256 * okay yet, they'll hit that in isp_start which will
2257 * freeze the queue again.
4075 * If this is past the first loop up or the loop is dead and if we'd frozen the simq, unfreeze it
4076 * now so that CAM can start sending us commands.
4077 *
4078 * If the FC state isn't okay yet, they'll hit that in isp_start which will freeze the queue again
4079 * or kill the commands, as appropriate.
2258 */
4080 */
2259 wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
2260 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
2261 if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
2262 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2263 "isp_kthread: releasing simq");
2264 xpt_release_simq(isp->isp_sim, 1);
4081
4082 if (FCPARAM(isp, chan)->loop_seen_once || fc->loop_dead) {
4083 wasfrozen = fc->simqfrozen & SIMQFRZ_LOOPDOWN;
4084 fc->simqfrozen &= ~SIMQFRZ_LOOPDOWN;
4085 if (wasfrozen && fc->simqfrozen == 0) {
4086 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "%s: Chan %d releasing simq", __func__, chan);
4087 xpt_release_simq(fc->sim, 1);
4088 }
2265 }
4089 }
2266 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2267 "isp_kthread: sleep time %d", slp);
2268#if __FreeBSD_version < 700037
2269 tsleep(ISP_KT_WCHAN(isp), PRIBIO, "ispf", slp * hz);
2270#else
2271 msleep(ISP_KT_WCHAN(isp), &isp->isp_osinfo.lock,
2272 PRIBIO, "ispf", slp * hz);
2273#endif
4090
4091 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep time %d", __func__, chan, slp);
4092
4093 msleep(fc, &isp->isp_osinfo.lock, PRIBIO, "ispf", slp * hz);
4094
2274 /*
2275 * If slp is zero, we're waking up for the first time after
2276 * things have been okay. In this case, we set a deferral state
2277 * for all commands and delay hysteresis seconds before starting
2278 * the FC state evaluation. This gives the loop/fabric a chance
2279 * to settle.
2280 */
4095 /*
4096 * If slp is zero, we're waking up for the first time after
4097 * things have been okay. In this case, we set a deferral state
4098 * for all commands and delay hysteresis seconds before starting
4099 * the FC state evaluation. This gives the loop/fabric a chance
4100 * to settle.
4101 */
2281 if (slp == 0 && isp->isp_osinfo.hysteresis) {
2282 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2283 "isp_kthread: sleep hysteresis tick time %d",
2284 isp->isp_osinfo.hysteresis * hz);
2285#if __FreeBSD_version < 700037
2286 (void) tsleep(&isp_fabric_hysteresis, PRIBIO, "ispT",
2287 (isp->isp_osinfo.hysteresis * hz));
2288#else
2289 (void) msleep(&isp_fabric_hysteresis,
2290 &isp->isp_osinfo.lock, PRIBIO, "ispT",
2291 (isp->isp_osinfo.hysteresis * hz));
2292#endif
4102 if (slp == 0 && fc->hysteresis) {
4103 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep hysteresis ticks %d", __func__, chan, fc->hysteresis * hz);
4104 (void) msleep(&isp_fabric_hysteresis, &isp->isp_osinfo.lock, PRIBIO, "ispT", (fc->hysteresis * hz));
2293 }
2294 }
4105 }
4106 }
2295#if __FreeBSD_version < 500000
2296 splx(s);
2297#elif __FreeBSD_version < 700037
2298 mtx_unlock(&Giant);
2299#else
2300 mtx_unlock(&isp->isp_osinfo.lock);
4107 mtx_unlock(&isp->isp_osinfo.lock);
2301#endif
2302}
2303
4108}
4109
2304#if __FreeBSD_version < 500000
2305static void isp_action_wrk(struct cam_sim *, union ccb *);
2306static void
2307isp_action(struct cam_sim *sim, union ccb *ccb)
2308{
4110static void
4111isp_action(struct cam_sim *sim, union ccb *ccb)
4112{
2309 ispsoftc_t *isp = (ispsoftc_t *)cam_sim_softc(sim);
2310 ISP_LOCK(isp);
2311 isp_action_wrk(sim, ccb);
2312 ISP_UNLOCK(isp);
2313}
2314#define isp_action isp_action_wrk
2315#endif
2316
2317static void
2318isp_action(struct cam_sim *sim, union ccb *ccb)
2319{
2320 int bus, tgt, ts, error, lim;
2321 ispsoftc_t *isp;
2322 struct ccb_trans_settings *cts;
2323
2324 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
2325
2326 isp = (ispsoftc_t *)cam_sim_softc(sim);
4113 int bus, tgt, ts, error, lim;
4114 ispsoftc_t *isp;
4115 struct ccb_trans_settings *cts;
4116
4117 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
4118
4119 isp = (ispsoftc_t *)cam_sim_softc(sim);
2327 if (isp->isp_state != ISP_RUNSTATE &&
2328 ccb->ccb_h.func_code == XPT_SCSI_IO) {
4120 mtx_assert(&isp->isp_lock, MA_OWNED);
4121
4122 if (isp->isp_state != ISP_RUNSTATE && ccb->ccb_h.func_code == XPT_SCSI_IO) {
2329 isp_init(isp);
2330 if (isp->isp_state != ISP_INITSTATE) {
2331 /*
2332 * Lie. Say it was a selection timeout.
2333 */
2334 ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
2335 xpt_freeze_devq(ccb->ccb_h.path, 1);
2336 xpt_done(ccb);
2337 return;
2338 }
2339 isp->isp_state = ISP_RUNSTATE;
2340 }
2341 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
2342 ISP_PCMD(ccb) = NULL;
2343
2344 switch (ccb->ccb_h.func_code) {
2345 case XPT_SCSI_IO: /* Execute the requested I/O operation */
4123 isp_init(isp);
4124 if (isp->isp_state != ISP_INITSTATE) {
4125 /*
4126 * Lie. Say it was a selection timeout.
4127 */
4128 ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
4129 xpt_freeze_devq(ccb->ccb_h.path, 1);
4130 xpt_done(ccb);
4131 return;
4132 }
4133 isp->isp_state = ISP_RUNSTATE;
4134 }
4135 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
4136 ISP_PCMD(ccb) = NULL;
4137
4138 switch (ccb->ccb_h.func_code) {
4139 case XPT_SCSI_IO: /* Execute the requested I/O operation */
4140 bus = XS_CHANNEL(ccb);
2346 /*
2347 * Do a couple of preliminary checks...
2348 */
2349 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
2350 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
2351 ccb->ccb_h.status = CAM_REQ_INVALID;
2352 xpt_done(ccb);
2353 break;

--- 11 unchanged lines hidden (view full) ---

2365 xpt_done(ccb);
2366 break;
2367 }
2368#endif
2369 ccb->csio.scsi_status = SCSI_STATUS_OK;
2370 if (isp_get_pcmd(isp, ccb)) {
2371 isp_prt(isp, ISP_LOGWARN, "out of PCMDs");
2372 cam_freeze_devq(ccb->ccb_h.path);
4141 /*
4142 * Do a couple of preliminary checks...
4143 */
4144 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
4145 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
4146 ccb->ccb_h.status = CAM_REQ_INVALID;
4147 xpt_done(ccb);
4148 break;

--- 11 unchanged lines hidden (view full) ---

4160 xpt_done(ccb);
4161 break;
4162 }
4163#endif
4164 ccb->csio.scsi_status = SCSI_STATUS_OK;
4165 if (isp_get_pcmd(isp, ccb)) {
4166 isp_prt(isp, ISP_LOGWARN, "out of PCMDs");
4167 cam_freeze_devq(ccb->ccb_h.path);
2373 cam_release_devq(ccb->ccb_h.path,
2374 RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
4168 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
2375 xpt_done(ccb);
2376 break;
2377 }
2378 error = isp_start((XS_T *) ccb);
2379 switch (error) {
2380 case CMD_QUEUED:
2381 XS_CMD_S_CLEAR(ccb);
2382 ccb->ccb_h.status |= CAM_SIM_QUEUED;
2383 if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
2384 break;
2385 }
2386 ts = ccb->ccb_h.timeout;
2387 if (ts == CAM_TIME_DEFAULT) {
2388 ts = 60*1000;
2389 }
2390 ts = isp_mstohz(ts);
4169 xpt_done(ccb);
4170 break;
4171 }
4172 error = isp_start((XS_T *) ccb);
4173 switch (error) {
4174 case CMD_QUEUED:
4175 XS_CMD_S_CLEAR(ccb);
4176 ccb->ccb_h.status |= CAM_SIM_QUEUED;
4177 if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
4178 break;
4179 }
4180 ts = ccb->ccb_h.timeout;
4181 if (ts == CAM_TIME_DEFAULT) {
4182 ts = 60*1000;
4183 }
4184 ts = isp_mstohz(ts);
2391 callout_reset(&PISP_PCMD(ccb)->wdog, ts,
2392 isp_watchdog, ccb);
4185 callout_reset(&PISP_PCMD(ccb)->wdog, ts, isp_watchdog, ccb);
2393 break;
2394 case CMD_RQLATER:
2395 /*
4186 break;
4187 case CMD_RQLATER:
4188 /*
2396 * Handle initial and subsequent loop down cases
4189 * We get this result for FC devices if the loop state isn't ready yet
4190 * or if the device in question has gone zombie on us.
4191 *
4192 * If we've never seen Loop UP at all, we requeue this request and wait
4193 * for the initial loop up delay to expire.
2397 */
4194 */
2398 if (FCPARAM(isp)->loop_seen_once == 0) {
2399 lim = isp_quickboot_time;
2400 } else {
2401 lim = isp->isp_osinfo.loop_down_limit;
2402 }
2403 if (isp->isp_osinfo.loop_down_time >= lim) {
2404 isp_prt(isp, ISP_LOGDEBUG0,
2405 "%d.%d downtime (%d) > lim (%d)",
2406 XS_TGT(ccb), XS_LUN(ccb),
2407 isp->isp_osinfo.loop_down_time, lim);
2408 ccb->ccb_h.status =
2409 CAM_SEL_TIMEOUT|CAM_DEV_QFRZN;
4195 lim = ISP_FC_PC(isp, bus)->loop_down_limit;
4196 if (FCPARAM(isp, bus)->loop_seen_once == 0 || ISP_FC_PC(isp, bus)->loop_down_time >= lim) {
4197 if (FCPARAM(isp, bus)->loop_seen_once == 0) {
4198 isp_prt(isp, ISP_LOGDEBUG0, "%d.%d loop not seen yet @ %lu", XS_TGT(ccb), XS_LUN(ccb), (unsigned long) time_uptime);
4199 } else {
4200 isp_prt(isp, ISP_LOGDEBUG0, "%d.%d downtime (%d) > lim (%d)", XS_TGT(ccb), XS_LUN(ccb), ISP_FC_PC(isp, bus)->loop_down_time, lim);
4201 }
4202 ccb->ccb_h.status = CAM_SEL_TIMEOUT|CAM_DEV_QFRZN;
2410 xpt_freeze_devq(ccb->ccb_h.path, 1);
2411 isp_free_pcmd(isp, ccb);
2412 xpt_done(ccb);
2413 break;
2414 }
4203 xpt_freeze_devq(ccb->ccb_h.path, 1);
4204 isp_free_pcmd(isp, ccb);
4205 xpt_done(ccb);
4206 break;
4207 }
2415 isp_prt(isp, ISP_LOGDEBUG0,
2416 "%d.%d retry later", XS_TGT(ccb), XS_LUN(ccb));
2417 /*
2418 * Otherwise, retry in a while.
2419 */
4208 isp_prt(isp, ISP_LOGDEBUG0, "%d.%d retry later", XS_TGT(ccb), XS_LUN(ccb));
2420 cam_freeze_devq(ccb->ccb_h.path);
4209 cam_freeze_devq(ccb->ccb_h.path);
2421 cam_release_devq(ccb->ccb_h.path,
2422 RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
4210 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
2423 XS_SETERR(ccb, CAM_REQUEUE_REQ);
2424 isp_free_pcmd(isp, ccb);
2425 xpt_done(ccb);
2426 break;
2427 case CMD_EAGAIN:
4211 XS_SETERR(ccb, CAM_REQUEUE_REQ);
4212 isp_free_pcmd(isp, ccb);
4213 xpt_done(ccb);
4214 break;
4215 case CMD_EAGAIN:
2428 XS_SETERR(ccb, CAM_REQUEUE_REQ);
2429 isp_free_pcmd(isp, ccb);
4216 isp_free_pcmd(isp, ccb);
4217 cam_freeze_devq(ccb->ccb_h.path);
4218 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0);
4219 XS_SETERR(ccb, CAM_REQUEUE_REQ);
2430 xpt_done(ccb);
2431 break;
2432 case CMD_COMPLETE:
2433 isp_done((struct ccb_scsiio *) ccb);
2434 break;
2435 default:
4220 xpt_done(ccb);
4221 break;
4222 case CMD_COMPLETE:
4223 isp_done((struct ccb_scsiio *) ccb);
4224 break;
4225 default:
2436 isp_prt(isp, ISP_LOGERR,
2437 "What's this? 0x%x at %d in file %s",
2438 error, __LINE__, __FILE__);
4226 isp_prt(isp, ISP_LOGERR, "What's this? 0x%x at %d in file %s", error, __LINE__, __FILE__);
2439 XS_SETERR(ccb, CAM_REQ_CMP_ERR);
2440 isp_free_pcmd(isp, ccb);
2441 xpt_done(ccb);
2442 }
2443 break;
2444
2445#ifdef ISP_TARGET_MODE
4227 XS_SETERR(ccb, CAM_REQ_CMP_ERR);
4228 isp_free_pcmd(isp, ccb);
4229 xpt_done(ccb);
4230 }
4231 break;
4232
4233#ifdef ISP_TARGET_MODE
2446 case XPT_EN_LUN: /* Enable LUN as a target */
2447 {
2448 int seq, i;
2449 seq = isp_en_lun(isp, ccb);
2450 if (seq < 0) {
2451 xpt_done(ccb);
2452 break;
4234 case XPT_EN_LUN: /* Enable/Disable LUN as a target */
4235 if (ccb->cel.enable) {
4236 isp_enable_lun(isp, ccb);
4237 } else {
4238 isp_disable_lun(isp, ccb);
2453 }
4239 }
2454 for (i = 0; isp->isp_osinfo.leact[seq] && i < 30 * 1000; i++) {
2455 uint32_t isr;
2456 uint16_t sema, mbox;
2457 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
2458 isp_intr(isp, isr, sema, mbox);
2459 }
2460 DELAY(1000);
2461 }
2462 break;
4240 break;
2463 }
2464 case XPT_NOTIFY_ACK: /* recycle notify ack */
2465 case XPT_IMMED_NOTIFY: /* Add Immediate Notify Resource */
4241 case XPT_IMMEDIATE_NOTIFY: /* Add Immediate Notify Resource */
2466 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */
2467 {
4242 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */
4243 {
2468 tstate_t *tptr =
2469 get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
4244 tstate_t *tptr = get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
2470 if (tptr == NULL) {
4245 if (tptr == NULL) {
2471 ccb->ccb_h.status = CAM_LUN_INVALID;
2472 xpt_done(ccb);
4246 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
4247 }
4248 if (tptr == NULL) {
4249 const char *str;
4250 uint32_t tag;
4251
4252 if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
4253 str = "XPT_IMMEDIATE_NOTIFY";
4254 tag = ccb->cin1.seq_id;
4255 } else {
4256 tag = ccb->atio.tag_id;
4257 str = "XPT_ACCEPT_TARGET_IO";
4258 }
4259 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] no state pointer found for %s\n", __func__, tag, str);
4260 dump_tstates(isp, XS_CHANNEL(ccb));
4261 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2473 break;
2474 }
2475 ccb->ccb_h.sim_priv.entries[0].field = 0;
2476 ccb->ccb_h.sim_priv.entries[1].ptr = isp;
2477 ccb->ccb_h.flags = 0;
2478
2479 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
4262 break;
4263 }
4264 ccb->ccb_h.sim_priv.entries[0].field = 0;
4265 ccb->ccb_h.sim_priv.entries[1].ptr = isp;
4266 ccb->ccb_h.flags = 0;
4267
4268 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
2480 /*
2481 * Note that the command itself may not be done-
2482 * it may not even have had the first CTIO sent.
2483 */
4269 if (ccb->atio.tag_id) {
4270 atio_private_data_t *atp = isp_get_atpd(isp, tptr, ccb->atio.tag_id);
4271 if (atp) {
4272 isp_put_atpd(isp, tptr, atp);
4273 }
4274 }
2484 tptr->atio_count++;
4275 tptr->atio_count++;
2485 isp_prt(isp, ISP_LOGTDEBUG0,
2486 "Put FREE ATIO, lun %d, count now %d",
2487 ccb->ccb_h.target_lun, tptr->atio_count);
2488 SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h,
2489 sim_links.sle);
2490 } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
4276 SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle);
4277 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE ATIO (tag id 0x%x), count now %d\n",
4278 ((struct ccb_accept_tio *)ccb)->tag_id, tptr->atio_count);
4279 } else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
4280 if (ccb->cin1.tag_id) {
4281 inot_private_data_t *ntp = isp_find_ntpd(isp, tptr, ccb->cin1.tag_id, ccb->cin1.seq_id);
4282 if (ntp) {
4283 isp_put_ntpd(isp, tptr, ntp);
4284 }
4285 }
2491 tptr->inot_count++;
4286 tptr->inot_count++;
2492 isp_prt(isp, ISP_LOGTDEBUG0,
2493 "Put FREE INOT, lun %d, count now %d",
2494 ccb->ccb_h.target_lun, tptr->inot_count);
2495 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h,
2496 sim_links.sle);
2497 } else {
2498 isp_prt(isp, ISP_LOGWARN, "Got Notify ACK");;
4287 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
4288 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
4289 ((struct ccb_immediate_notify *)ccb)->seq_id, tptr->inot_count);
2499 }
2500 rls_lun_statep(isp, tptr);
2501 ccb->ccb_h.status = CAM_REQ_INPROG;
2502 break;
2503 }
4290 }
4291 rls_lun_statep(isp, tptr);
4292 ccb->ccb_h.status = CAM_REQ_INPROG;
4293 break;
4294 }
2504 case XPT_CONT_TARGET_IO:
4295 case XPT_NOTIFY_ACKNOWLEDGE: /* notify ack */
2505 {
4296 {
2506 isp_target_start_ctio(isp, ccb);
4297 tstate_t *tptr;
4298 inot_private_data_t *ntp;
4299
4300 /*
4301 * XXX: Because we cannot guarantee that the path information in the notify acknowledge ccb
4302 * XXX: matches that for the immediate notify, we have to *search* for the notify structure
4303 */
4304 /*
4305 * All the relevant path information is in the associated immediate notify
4306 */
4307 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] NOTIFY ACKNOWLEDGE for 0x%x seen\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id);
4308 ntp = get_ntp_from_tagdata(isp, ccb->cna2.tag_id, ccb->cna2.seq_id, &tptr);
4309 if (ntp == NULL) {
4310 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] XPT_NOTIFY_ACKNOWLEDGE of 0x%x cannot find ntp private data\n", __func__,
4311 ccb->cna2.tag_id, ccb->cna2.seq_id);
4312 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
4313 xpt_done(ccb);
4314 break;
4315 }
4316 if (isp_handle_platform_target_notify_ack(isp, &ntp->rd.nt)) {
4317 rls_lun_statep(isp, tptr);
4318 cam_freeze_devq(ccb->ccb_h.path);
4319 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
4320 XS_SETERR(ccb, CAM_REQUEUE_REQ);
4321 break;
4322 }
4323 isp_put_ntpd(isp, tptr, ntp);
4324 rls_lun_statep(isp, tptr);
4325 ccb->ccb_h.status = CAM_REQ_CMP;
4326 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] calling xpt_done for tag 0x%x\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id);
4327 xpt_done(ccb);
2507 break;
2508 }
4328 break;
4329 }
4330 case XPT_CONT_TARGET_IO:
4331 isp_target_start_ctio(isp, ccb);
4332 break;
2509#endif
2510 case XPT_RESET_DEV: /* BDR the specified SCSI device */
2511
2512 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
2513 tgt = ccb->ccb_h.target_id;
2514 tgt |= (bus << 16);
2515
4333#endif
4334 case XPT_RESET_DEV: /* BDR the specified SCSI device */
4335
4336 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
4337 tgt = ccb->ccb_h.target_id;
4338 tgt |= (bus << 16);
4339
2516 error = isp_control(isp, ISPCTL_RESET_DEV, &tgt);
4340 error = isp_control(isp, ISPCTL_RESET_DEV, bus, tgt);
2517 if (error) {
2518 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2519 } else {
2520 ccb->ccb_h.status = CAM_REQ_CMP;
2521 }
2522 xpt_done(ccb);
2523 break;
2524 case XPT_ABORT: /* Abort the specified CCB */
2525 {
2526 union ccb *accb = ccb->cab.abort_ccb;
2527 switch (accb->ccb_h.func_code) {
2528#ifdef ISP_TARGET_MODE
2529 case XPT_ACCEPT_TARGET_IO:
4341 if (error) {
4342 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4343 } else {
4344 ccb->ccb_h.status = CAM_REQ_CMP;
4345 }
4346 xpt_done(ccb);
4347 break;
4348 case XPT_ABORT: /* Abort the specified CCB */
4349 {
4350 union ccb *accb = ccb->cab.abort_ccb;
4351 switch (accb->ccb_h.func_code) {
4352#ifdef ISP_TARGET_MODE
4353 case XPT_ACCEPT_TARGET_IO:
2530 case XPT_IMMED_NOTIFY:
2531 ccb->ccb_h.status = isp_abort_tgt_ccb(isp, ccb);
4354 isp_target_mark_aborted(isp, accb);
2532 break;
4355 break;
2533 case XPT_CONT_TARGET_IO:
2534 isp_prt(isp, ISP_LOGERR, "cannot abort CTIOs yet");
2535 ccb->ccb_h.status = CAM_UA_ABORT;
2536 break;
2537#endif
2538 case XPT_SCSI_IO:
2539 error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
2540 if (error) {
2541 ccb->ccb_h.status = CAM_UA_ABORT;
2542 } else {
2543 ccb->ccb_h.status = CAM_REQ_CMP;
2544 }
2545 break;
2546 default:
2547 ccb->ccb_h.status = CAM_REQ_INVALID;
2548 break;
2549 }
2550 xpt_done(ccb);
2551 break;
2552 }
4356#endif
4357 case XPT_SCSI_IO:
4358 error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
4359 if (error) {
4360 ccb->ccb_h.status = CAM_UA_ABORT;
4361 } else {
4362 ccb->ccb_h.status = CAM_REQ_CMP;
4363 }
4364 break;
4365 default:
4366 ccb->ccb_h.status = CAM_REQ_INVALID;
4367 break;
4368 }
4369 xpt_done(ccb);
4370 break;
4371 }
2553#ifdef CAM_NEW_TRAN_CODE
2554#define IS_CURRENT_SETTINGS(c) (c->type == CTS_TYPE_CURRENT_SETTINGS)
4372#define IS_CURRENT_SETTINGS(c) (c->type == CTS_TYPE_CURRENT_SETTINGS)
2555#else
2556#define IS_CURRENT_SETTINGS(c) (c->flags & CCB_TRANS_CURRENT_SETTINGS)
2557#endif
2558 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */
2559 cts = &ccb->cts;
2560 if (!IS_CURRENT_SETTINGS(cts)) {
2561 ccb->ccb_h.status = CAM_REQ_INVALID;
2562 xpt_done(ccb);
2563 break;
2564 }
2565 tgt = cts->ccb_h.target_id;
4373 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */
4374 cts = &ccb->cts;
4375 if (!IS_CURRENT_SETTINGS(cts)) {
4376 ccb->ccb_h.status = CAM_REQ_INVALID;
4377 xpt_done(ccb);
4378 break;
4379 }
4380 tgt = cts->ccb_h.target_id;
4381 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2566 if (IS_SCSI(isp)) {
4382 if (IS_SCSI(isp)) {
2567#ifndef CAM_NEW_TRAN_CODE
2568 sdparam *sdp = isp->isp_param;
4383 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
4384 struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
4385 sdparam *sdp = SDPARAM(isp, bus);
2569 uint16_t *dptr;
2570
4386 uint16_t *dptr;
4387
2571 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2572
2573 sdp += bus;
2574 /*
2575 * We always update (internally) from goal_flags
2576 * so any request to change settings just gets
2577 * vectored to that location.
2578 */
2579 dptr = &sdp->isp_devparam[tgt].goal_flags;
2580
2581 /*
2582 * Note that these operations affect the
2583 * the goal flags (goal_flags)- not
2584 * the current state flags. Then we mark
2585 * things so that the next operation to
2586 * this HBA will cause the update to occur.
2587 */
2588 if (cts->valid & CCB_TRANS_DISC_VALID) {
2589 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
2590 *dptr |= DPARM_DISC;
2591 } else {
2592 *dptr &= ~DPARM_DISC;
2593 }
2594 }
2595 if (cts->valid & CCB_TRANS_TQ_VALID) {
2596 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
2597 *dptr |= DPARM_TQING;
2598 } else {
2599 *dptr &= ~DPARM_TQING;
2600 }
2601 }
2602 if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) {
2603 switch (cts->bus_width) {
2604 case MSG_EXT_WDTR_BUS_16_BIT:
2605 *dptr |= DPARM_WIDE;
2606 break;
2607 default:
2608 *dptr &= ~DPARM_WIDE;
2609 }
2610 }
2611 /*
2612 * Any SYNC RATE of nonzero and SYNC_OFFSET
2613 * of nonzero will cause us to go to the
2614 * selected (from NVRAM) maximum value for
2615 * this device. At a later point, we'll
2616 * allow finer control.
2617 */
2618 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) &&
2619 (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) &&
2620 (cts->sync_offset > 0)) {
2621 *dptr |= DPARM_SYNC;
2622 } else {
2623 *dptr &= ~DPARM_SYNC;
2624 }
2625 *dptr |= DPARM_SAFE_DFLT;
2626#else
2627 struct ccb_trans_settings_scsi *scsi =
2628 &cts->proto_specific.scsi;
2629 struct ccb_trans_settings_spi *spi =
2630 &cts->xport_specific.spi;
2631 sdparam *sdp = isp->isp_param;
2632 uint16_t *dptr;
2633
2634 if (spi->valid == 0 && scsi->valid == 0) {
2635 ccb->ccb_h.status = CAM_REQ_CMP;
2636 xpt_done(ccb);
2637 break;
2638 }
4388 if (spi->valid == 0 && scsi->valid == 0) {
4389 ccb->ccb_h.status = CAM_REQ_CMP;
4390 xpt_done(ccb);
4391 break;
4392 }
2639
2640 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2641 sdp += bus;
4393
2642 /*
2643 * We always update (internally) from goal_flags
2644 * so any request to change settings just gets
2645 * vectored to that location.
2646 */
2647 dptr = &sdp->isp_devparam[tgt].goal_flags;
2648
2649 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {

--- 15 unchanged lines hidden (view full) ---

2665 *dptr |= DPARM_WIDE;
2666 else
2667 *dptr &= ~DPARM_WIDE;
2668 }
2669
2670 /*
2671 * XXX: FIX ME
2672 */
4394 /*
4395 * We always update (internally) from goal_flags
4396 * so any request to change settings just gets
4397 * vectored to that location.
4398 */
4399 dptr = &sdp->isp_devparam[tgt].goal_flags;
4400
4401 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {

--- 15 unchanged lines hidden (view full) ---

4417 *dptr |= DPARM_WIDE;
4418 else
4419 *dptr &= ~DPARM_WIDE;
4420 }
4421
4422 /*
4423 * XXX: FIX ME
4424 */
2673 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) &&
2674 (spi->valid & CTS_SPI_VALID_SYNC_RATE) &&
2675 (spi->sync_period && spi->sync_offset)) {
4425 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) && (spi->valid & CTS_SPI_VALID_SYNC_RATE) && (spi->sync_period && spi->sync_offset)) {
2676 *dptr |= DPARM_SYNC;
2677 /*
2678 * XXX: CHECK FOR LEGALITY
2679 */
4426 *dptr |= DPARM_SYNC;
4427 /*
4428 * XXX: CHECK FOR LEGALITY
4429 */
2680 sdp->isp_devparam[tgt].goal_period =
2681 spi->sync_period;
2682 sdp->isp_devparam[tgt].goal_offset =
2683 spi->sync_offset;
4430 sdp->isp_devparam[tgt].goal_period = spi->sync_period;
4431 sdp->isp_devparam[tgt].goal_offset = spi->sync_offset;
2684 } else {
2685 *dptr &= ~DPARM_SYNC;
2686 }
4432 } else {
4433 *dptr &= ~DPARM_SYNC;
4434 }
2687#endif
2688 isp_prt(isp, ISP_LOGDEBUG0,
2689 "SET (%d.%d.%d) to flags %x off %x per %x",
2690 bus, tgt, cts->ccb_h.target_lun,
2691 sdp->isp_devparam[tgt].goal_flags,
2692 sdp->isp_devparam[tgt].goal_offset,
2693 sdp->isp_devparam[tgt].goal_period);
4435 isp_prt(isp, ISP_LOGDEBUG0, "SET (%d.%d.%d) to flags %x off %x per %x", bus, tgt, cts->ccb_h.target_lun, sdp->isp_devparam[tgt].goal_flags,
4436 sdp->isp_devparam[tgt].goal_offset, sdp->isp_devparam[tgt].goal_period);
2694 sdp->isp_devparam[tgt].dev_update = 1;
4437 sdp->isp_devparam[tgt].dev_update = 1;
2695 isp->isp_update |= (1 << bus);
4438 sdp->update = 1;
2696 }
2697 ccb->ccb_h.status = CAM_REQ_CMP;
2698 xpt_done(ccb);
2699 break;
2700 case XPT_GET_TRAN_SETTINGS:
2701 cts = &ccb->cts;
2702 tgt = cts->ccb_h.target_id;
4439 }
4440 ccb->ccb_h.status = CAM_REQ_CMP;
4441 xpt_done(ccb);
4442 break;
4443 case XPT_GET_TRAN_SETTINGS:
4444 cts = &ccb->cts;
4445 tgt = cts->ccb_h.target_id;
4446 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2703 if (IS_FC(isp)) {
4447 if (IS_FC(isp)) {
2704#ifndef CAM_NEW_TRAN_CODE
2705 /*
2706 * a lot of normal SCSI things don't make sense.
2707 */
2708 cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
2709 cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2710 /*
2711 * How do you measure the width of a high
2712 * speed serial bus? Well, in bytes.
2713 *
2714 * Offset and period make no sense, though, so we set
2715 * (above) a 'base' transfer speed to be gigabit.
2716 */
2717 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2718#else
2719 fcparam *fcp = isp->isp_param;
2720 struct ccb_trans_settings_scsi *scsi =
2721 &cts->proto_specific.scsi;
2722 struct ccb_trans_settings_fc *fc =
2723 &cts->xport_specific.fc;
4448 fcparam *fcp = FCPARAM(isp, bus);
4449 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
4450 struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
2724
2725 cts->protocol = PROTO_SCSI;
2726 cts->protocol_version = SCSI_REV_2;
2727 cts->transport = XPORT_FC;
2728 cts->transport_version = 0;
2729
2730 scsi->valid = CTS_SCSI_VALID_TQ;
2731 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
2732 fc->valid = CTS_FC_VALID_SPEED;
2733 fc->bitrate = 100000;
4451
4452 cts->protocol = PROTO_SCSI;
4453 cts->protocol_version = SCSI_REV_2;
4454 cts->transport = XPORT_FC;
4455 cts->transport_version = 0;
4456
4457 scsi->valid = CTS_SCSI_VALID_TQ;
4458 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
4459 fc->valid = CTS_FC_VALID_SPEED;
4460 fc->bitrate = 100000;
2734 if (fcp->isp_gbspeed == 4 || fcp->isp_gbspeed == 2)
2735 fc->bitrate *= fcp->isp_gbspeed;
4461 fc->bitrate *= fcp->isp_gbspeed;
2736 if (tgt > 0 && tgt < MAX_FC_TARG) {
2737 fcportdb_t *lp = &fcp->portdb[tgt];
2738 fc->wwnn = lp->node_wwn;
2739 fc->wwpn = lp->port_wwn;
2740 fc->port = lp->portid;
4462 if (tgt > 0 && tgt < MAX_FC_TARG) {
4463 fcportdb_t *lp = &fcp->portdb[tgt];
4464 fc->wwnn = lp->node_wwn;
4465 fc->wwpn = lp->port_wwn;
4466 fc->port = lp->portid;
2741 fc->valid |= CTS_FC_VALID_WWNN |
2742 CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT;
4467 fc->valid |= CTS_FC_VALID_WWNN | CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT;
2743 }
4468 }
2744#endif
2745 } else {
4469 } else {
2746#ifdef CAM_NEW_TRAN_CODE
2747 struct ccb_trans_settings_scsi *scsi =
2748 &cts->proto_specific.scsi;
2749 struct ccb_trans_settings_spi *spi =
2750 &cts->xport_specific.spi;
2751#endif
2752 sdparam *sdp = isp->isp_param;
2753 int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
4470 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
4471 struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
4472 sdparam *sdp = SDPARAM(isp, bus);
2754 uint16_t dval, pval, oval;
2755
4473 uint16_t dval, pval, oval;
4474
2756 sdp += bus;
2757
2758 if (IS_CURRENT_SETTINGS(cts)) {
2759 sdp->isp_devparam[tgt].dev_refresh = 1;
4475 if (IS_CURRENT_SETTINGS(cts)) {
4476 sdp->isp_devparam[tgt].dev_refresh = 1;
2760 isp->isp_update |= (1 << bus);
2761 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS,
2762 NULL);
4477 sdp->update = 1;
4478 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus);
2763 dval = sdp->isp_devparam[tgt].actv_flags;
2764 oval = sdp->isp_devparam[tgt].actv_offset;
2765 pval = sdp->isp_devparam[tgt].actv_period;
2766 } else {
2767 dval = sdp->isp_devparam[tgt].nvrm_flags;
2768 oval = sdp->isp_devparam[tgt].nvrm_offset;
2769 pval = sdp->isp_devparam[tgt].nvrm_period;
2770 }
2771
4479 dval = sdp->isp_devparam[tgt].actv_flags;
4480 oval = sdp->isp_devparam[tgt].actv_offset;
4481 pval = sdp->isp_devparam[tgt].actv_period;
4482 } else {
4483 dval = sdp->isp_devparam[tgt].nvrm_flags;
4484 oval = sdp->isp_devparam[tgt].nvrm_offset;
4485 pval = sdp->isp_devparam[tgt].nvrm_period;
4486 }
4487
2772#ifndef CAM_NEW_TRAN_CODE
2773 cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
2774
2775 if (dval & DPARM_DISC) {
2776 cts->flags |= CCB_TRANS_DISC_ENB;
2777 }
2778 if (dval & DPARM_TQING) {
2779 cts->flags |= CCB_TRANS_TAG_ENB;
2780 }
2781 if (dval & DPARM_WIDE) {
2782 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2783 } else {
2784 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2785 }
2786 cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
2787 CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2788
2789 if ((dval & DPARM_SYNC) && oval != 0) {
2790 cts->sync_period = pval;
2791 cts->sync_offset = oval;
2792 cts->valid |=
2793 CCB_TRANS_SYNC_RATE_VALID |
2794 CCB_TRANS_SYNC_OFFSET_VALID;
2795 }
2796#else
2797 cts->protocol = PROTO_SCSI;
2798 cts->protocol_version = SCSI_REV_2;
2799 cts->transport = XPORT_SPI;
2800 cts->transport_version = 2;
2801
2802 spi->valid = 0;
2803 scsi->valid = 0;
2804 spi->flags = 0;

--- 18 unchanged lines hidden (view full) ---

2823 }
2824 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
2825 scsi->valid = CTS_SCSI_VALID_TQ;
2826 if (dval & DPARM_TQING) {
2827 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
2828 }
2829 spi->valid |= CTS_SPI_VALID_DISC;
2830 }
4488 cts->protocol = PROTO_SCSI;
4489 cts->protocol_version = SCSI_REV_2;
4490 cts->transport = XPORT_SPI;
4491 cts->transport_version = 2;
4492
4493 spi->valid = 0;
4494 scsi->valid = 0;
4495 spi->flags = 0;

--- 18 unchanged lines hidden (view full) ---

4514 }
4515 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
4516 scsi->valid = CTS_SCSI_VALID_TQ;
4517 if (dval & DPARM_TQING) {
4518 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
4519 }
4520 spi->valid |= CTS_SPI_VALID_DISC;
4521 }
2831#endif
2832 isp_prt(isp, ISP_LOGDEBUG0,
2833 "GET %s (%d.%d.%d) to flags %x off %x per %x",
2834 IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
4522 isp_prt(isp, ISP_LOGDEBUG0, "GET %s (%d.%d.%d) to flags %x off %x per %x", IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
2835 bus, tgt, cts->ccb_h.target_lun, dval, oval, pval);
2836 }
2837 ccb->ccb_h.status = CAM_REQ_CMP;
2838 xpt_done(ccb);
2839 break;
2840
2841 case XPT_CALC_GEOMETRY:
4523 bus, tgt, cts->ccb_h.target_lun, dval, oval, pval);
4524 }
4525 ccb->ccb_h.status = CAM_REQ_CMP;
4526 xpt_done(ccb);
4527 break;
4528
4529 case XPT_CALC_GEOMETRY:
2842#if __FreeBSD_version < 500000
2843 {
2844 struct ccb_calc_geometry *ccg;
2845 u_int32_t secs_per_cylinder;
2846 u_int32_t size_mb;
4530 cam_calc_geometry(&ccb->ccg, 1);
4531 xpt_done(ccb);
4532 break;
2847
4533
2848 ccg = &ccb->ccg;
2849 if (ccg->block_size == 0) {
2850 ccb->ccb_h.status = CAM_REQ_INVALID;
4534 case XPT_RESET_BUS: /* Reset the specified bus */
4535 bus = cam_sim_bus(sim);
4536 error = isp_control(isp, ISPCTL_RESET_BUS, bus);
4537 if (error) {
4538 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2851 xpt_done(ccb);
2852 break;
2853 }
4539 xpt_done(ccb);
4540 break;
4541 }
2854 size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size);
2855 if (size_mb > 1024) {
2856 ccg->heads = 255;
2857 ccg->secs_per_track = 63;
4542 if (bootverbose) {
4543 xpt_print(ccb->ccb_h.path, "reset bus on channel %d\n", bus);
4544 }
4545 if (IS_FC(isp)) {
4546 xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, 0);
2858 } else {
4547 } else {
2859 ccg->heads = 64;
2860 ccg->secs_per_track = 32;
4548 xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, 0);
2861 }
4549 }
2862 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2863 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2864 ccb->ccb_h.status = CAM_REQ_CMP;
2865 xpt_done(ccb);
2866 break;
4550 ccb->ccb_h.status = CAM_REQ_CMP;
4551 xpt_done(ccb);
4552 break;
2867 }
2868#else
2869 {
2870 cam_calc_geometry(&ccb->ccg, /*extended*/1);
4553
4554 case XPT_TERM_IO: /* Terminate the I/O process */
4555 ccb->ccb_h.status = CAM_REQ_INVALID;
2871 xpt_done(ccb);
2872 break;
4556 xpt_done(ccb);
4557 break;
2873 }
4558
4559 case XPT_SET_SIM_KNOB: /* Set SIM knobs */
4560 {
4561 struct ccb_sim_knob *kp = &ccb->knob;
4562 fcparam *fcp;
4563
4564
4565 if (!IS_FC(isp)) {
4566 ccb->ccb_h.status = CAM_REQ_INVALID;
4567 xpt_done(ccb);
4568 break;
4569 }
4570
4571 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
4572 fcp = FCPARAM(isp, bus);
4573
4574 if (kp->xport_specific.fc.valid & KNOB_VALID_ADDRESS) {
4575 fcp->isp_wwnn = ISP_FC_PC(isp, bus)->def_wwnn = kp->xport_specific.fc.wwnn;
4576 fcp->isp_wwpn = ISP_FC_PC(isp, bus)->def_wwpn = kp->xport_specific.fc.wwpn;
4577isp_prt(isp, ISP_LOGALL, "Setting Channel %d wwns to 0x%jx 0x%jx", bus, fcp->isp_wwnn, fcp->isp_wwpn);
4578 }
4579 ccb->ccb_h.status = CAM_REQ_CMP;
4580 if (kp->xport_specific.fc.valid & KNOB_VALID_ROLE) {
4581 int rchange = 0;
4582 int newrole = 0;
4583
4584 switch (kp->xport_specific.fc.role) {
4585 case KNOB_ROLE_NONE:
4586 if (fcp->role != ISP_ROLE_NONE) {
4587 rchange = 1;
4588 newrole = ISP_ROLE_NONE;
4589 }
4590 break;
4591 case KNOB_ROLE_TARGET:
4592 if (fcp->role != ISP_ROLE_TARGET) {
4593 rchange = 1;
4594 newrole = ISP_ROLE_TARGET;
4595 }
4596 break;
4597 case KNOB_ROLE_INITIATOR:
4598 if (fcp->role != ISP_ROLE_INITIATOR) {
4599 rchange = 1;
4600 newrole = ISP_ROLE_INITIATOR;
4601 }
4602 break;
4603 case KNOB_ROLE_BOTH:
4604 if (fcp->role != ISP_ROLE_BOTH) {
4605 rchange = 1;
4606 newrole = ISP_ROLE_BOTH;
4607 }
4608 break;
4609 }
4610 if (rchange) {
4611 if (isp_fc_change_role(isp, bus, newrole) != 0) {
4612 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4613#ifdef ISP_TARGET_MODE
4614 } else if (newrole == ISP_ROLE_TARGET || newrole == ISP_ROLE_BOTH) {
4615 isp_enable_deferred_luns(isp, bus);
2874#endif
4616#endif
2875 case XPT_RESET_BUS: /* Reset the specified bus */
2876 bus = cam_sim_bus(sim);
2877 error = isp_control(isp, ISPCTL_RESET_BUS, &bus);
2878 if (error)
2879 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2880 else {
2881 if (bootverbose) {
2882 xpt_print(ccb->ccb_h.path, "reset bus\n");
4617 }
2883 }
4618 }
2884 if (cam_sim_bus(sim) && isp->isp_path2 != NULL)
2885 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
2886 else if (isp->isp_path != NULL)
2887 xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
2888 ccb->ccb_h.status = CAM_REQ_CMP;
2889 }
2890 xpt_done(ccb);
2891 break;
4619 }
4620 xpt_done(ccb);
4621 break;
4622 }
4623 case XPT_GET_SIM_KNOB: /* Set SIM knobs */
4624 {
4625 struct ccb_sim_knob *kp = &ccb->knob;
2892
4626
2893 case XPT_TERM_IO: /* Terminate the I/O process */
2894 ccb->ccb_h.status = CAM_REQ_INVALID;
4627 if (IS_FC(isp)) {
4628 fcparam *fcp;
4629
4630 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
4631 fcp = FCPARAM(isp, bus);
4632
4633 kp->xport_specific.fc.wwnn = fcp->isp_wwnn;
4634 kp->xport_specific.fc.wwpn = fcp->isp_wwpn;
4635 switch (fcp->role) {
4636 case ISP_ROLE_NONE:
4637 kp->xport_specific.fc.role = KNOB_ROLE_NONE;
4638 break;
4639 case ISP_ROLE_TARGET:
4640 kp->xport_specific.fc.role = KNOB_ROLE_TARGET;
4641 break;
4642 case ISP_ROLE_INITIATOR:
4643 kp->xport_specific.fc.role = KNOB_ROLE_INITIATOR;
4644 break;
4645 case ISP_ROLE_BOTH:
4646 kp->xport_specific.fc.role = KNOB_ROLE_BOTH;
4647 break;
4648 }
4649 kp->xport_specific.fc.valid = KNOB_VALID_ADDRESS | KNOB_VALID_ROLE;
4650 ccb->ccb_h.status = CAM_REQ_CMP;
4651 } else {
4652 ccb->ccb_h.status = CAM_REQ_INVALID;
4653 }
2895 xpt_done(ccb);
2896 break;
4654 xpt_done(ccb);
4655 break;
2897
4656 }
2898 case XPT_PATH_INQ: /* Path routing inquiry */
2899 {
2900 struct ccb_pathinq *cpi = &ccb->cpi;
2901
2902 cpi->version_num = 1;
2903#ifdef ISP_TARGET_MODE
2904 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
2905#else
2906 cpi->target_sprt = 0;
2907#endif
2908 cpi->hba_eng_cnt = 0;
2909 cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
2910 cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
2911 cpi->bus_id = cam_sim_bus(sim);
4657 case XPT_PATH_INQ: /* Path routing inquiry */
4658 {
4659 struct ccb_pathinq *cpi = &ccb->cpi;
4660
4661 cpi->version_num = 1;
4662#ifdef ISP_TARGET_MODE
4663 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
4664#else
4665 cpi->target_sprt = 0;
4666#endif
4667 cpi->hba_eng_cnt = 0;
4668 cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
4669 cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
4670 cpi->bus_id = cam_sim_bus(sim);
4671 bus = cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
2912 if (IS_FC(isp)) {
4672 if (IS_FC(isp)) {
4673 fcparam *fcp = FCPARAM(isp, bus);
4674
2913 cpi->hba_misc = PIM_NOBUSRESET;
4675 cpi->hba_misc = PIM_NOBUSRESET;
4676
2914 /*
2915 * Because our loop ID can shift from time to time,
2916 * make our initiator ID out of range of our bus.
2917 */
2918 cpi->initiator_id = cpi->max_target + 1;
2919
2920 /*
4677 /*
4678 * Because our loop ID can shift from time to time,
4679 * make our initiator ID out of range of our bus.
4680 */
4681 cpi->initiator_id = cpi->max_target + 1;
4682
4683 /*
2921 * Set base transfer capabilities for Fibre Channel.
2922 * Technically not correct because we don't know
2923 * what media we're running on top of- but we'll
2924 * look good if we always say 100MB/s.
4684 * Set base transfer capabilities for Fibre Channel, for this HBA.
2925 */
4685 */
2926 cpi->base_transfer_speed = 100000;
2927 if (FCPARAM(isp)->isp_gbspeed == 4 ||
2928 FCPARAM(isp)->isp_gbspeed == 2)
2929 cpi->base_transfer_speed *=
2930 FCPARAM(isp)->isp_gbspeed;
4686 if (IS_24XX(isp)) {
4687 cpi->base_transfer_speed = 4000000;
4688 } else if (IS_23XX(isp)) {
4689 cpi->base_transfer_speed = 2000000;
4690 } else {
4691 cpi->base_transfer_speed = 1000000;
4692 }
2931 cpi->hba_inquiry = PI_TAG_ABLE;
4693 cpi->hba_inquiry = PI_TAG_ABLE;
2932#ifdef CAM_NEW_TRAN_CODE
2933 cpi->transport = XPORT_FC;
2934 cpi->transport_version = 0;
4694 cpi->transport = XPORT_FC;
4695 cpi->transport_version = 0;
2935#endif
4696 cpi->xport_specific.fc.wwnn = fcp->isp_wwnn;
4697 cpi->xport_specific.fc.wwpn = fcp->isp_wwpn;
4698 cpi->xport_specific.fc.port = fcp->isp_portid;
4699 cpi->xport_specific.fc.bitrate = fcp->isp_gbspeed * 1000;
2936 } else {
4700 } else {
2937 sdparam *sdp = isp->isp_param;
2938 sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
4701 sdparam *sdp = SDPARAM(isp, bus);
2939 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
2940 cpi->hba_misc = 0;
2941 cpi->initiator_id = sdp->isp_initiator_id;
2942 cpi->base_transfer_speed = 3300;
4702 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
4703 cpi->hba_misc = 0;
4704 cpi->initiator_id = sdp->isp_initiator_id;
4705 cpi->base_transfer_speed = 3300;
2943#ifdef CAM_NEW_TRAN_CODE
2944 cpi->transport = XPORT_SPI;
2945 cpi->transport_version = 2;
4706 cpi->transport = XPORT_SPI;
4707 cpi->transport_version = 2;
2946#endif
2947 }
4708 }
2948#ifdef CAM_NEW_TRAN_CODE
2949 cpi->protocol = PROTO_SCSI;
2950 cpi->protocol_version = SCSI_REV_2;
4709 cpi->protocol = PROTO_SCSI;
4710 cpi->protocol_version = SCSI_REV_2;
2951#endif
2952 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2953 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
2954 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2955 cpi->unit_number = cam_sim_unit(sim);
2956 cpi->ccb_h.status = CAM_REQ_CMP;
2957 xpt_done(ccb);
2958 break;
2959 }
2960 default:
2961 ccb->ccb_h.status = CAM_REQ_INVALID;
2962 xpt_done(ccb);
2963 break;
2964 }
2965}
2966
2967#define ISPDDB (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
2968
2969void
4711 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
4712 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
4713 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
4714 cpi->unit_number = cam_sim_unit(sim);
4715 cpi->ccb_h.status = CAM_REQ_CMP;
4716 xpt_done(ccb);
4717 break;
4718 }
4719 default:
4720 ccb->ccb_h.status = CAM_REQ_INVALID;
4721 xpt_done(ccb);
4722 break;
4723 }
4724}
4725
4726#define ISPDDB (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
4727
4728void
2970isp_done(struct ccb_scsiio *sccb)
4729isp_done(XS_T *sccb)
2971{
2972 ispsoftc_t *isp = XS_ISP(sccb);
2973
2974 if (XS_NOERR(sccb))
2975 XS_SETERR(sccb, CAM_REQ_CMP);
2976
4730{
4731 ispsoftc_t *isp = XS_ISP(sccb);
4732
4733 if (XS_NOERR(sccb))
4734 XS_SETERR(sccb, CAM_REQ_CMP);
4735
2977 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
2978 (sccb->scsi_status != SCSI_STATUS_OK)) {
4736 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && (sccb->scsi_status != SCSI_STATUS_OK)) {
2979 sccb->ccb_h.status &= ~CAM_STATUS_MASK;
4737 sccb->ccb_h.status &= ~CAM_STATUS_MASK;
2980 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) &&
2981 (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
4738 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
2982 sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
2983 } else {
2984 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
2985 }
2986 }
2987
2988 sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2989 if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4739 sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
4740 } else {
4741 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
4742 }
4743 }
4744
4745 sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4746 if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2990 isp_prt(isp, ISP_LOGDEBUG0,
2991 "target %d lun %d CAM status 0x%x SCSI status 0x%x",
2992 XS_TGT(sccb), XS_LUN(sccb), sccb->ccb_h.status,
2993 sccb->scsi_status);
4747 isp_prt(isp, ISP_LOGDEBUG0, "target %d lun %d CAM status 0x%x SCSI status 0x%x", XS_TGT(sccb), XS_LUN(sccb), sccb->ccb_h.status, sccb->scsi_status);
2994 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
2995 sccb->ccb_h.status |= CAM_DEV_QFRZN;
2996 xpt_freeze_devq(sccb->ccb_h.path, 1);
2997 }
2998 }
2999
4748 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
4749 sccb->ccb_h.status |= CAM_DEV_QFRZN;
4750 xpt_freeze_devq(sccb->ccb_h.path, 1);
4751 }
4752 }
4753
3000 if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) &&
3001 (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3002 xpt_print(sccb->ccb_h.path,
3003 "cam completion status 0x%x\n", sccb->ccb_h.status);
4754 if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) && (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4755 xpt_print(sccb->ccb_h.path, "cam completion status 0x%x\n", sccb->ccb_h.status);
3004 }
3005
3006 XS_CMD_S_DONE(sccb);
4756 }
4757
4758 XS_CMD_S_DONE(sccb);
3007 if (XS_CMD_WDOG_P(sccb) == 0) {
3008 callout_stop(&PISP_PCMD(sccb)->wdog);
3009 if (XS_CMD_GRACE_P(sccb)) {
3010 isp_prt(isp, ISP_LOGDEBUG2,
3011 "finished command on borrowed time");
3012 }
3013 XS_CMD_S_CLEAR(sccb);
3014 isp_free_pcmd(isp, (union ccb *) sccb);
3015 xpt_done((union ccb *) sccb);
3016 }
4759 callout_stop(&PISP_PCMD(sccb)->wdog);
4760 XS_CMD_S_CLEAR(sccb);
4761 isp_free_pcmd(isp, (union ccb *) sccb);
4762 xpt_done((union ccb *) sccb);
3017}
3018
4763}
4764
3019int
3020isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg)
4765void
4766isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
3021{
4767{
3022 int bus, rv = 0;
3023 static const char prom[] =
3024 "PortID 0x%06x handle 0x%x role %s %s\n"
3025 " WWNN 0x%08x%08x WWPN 0x%08x%08x";
3026 static const char prom2[] =
3027 "PortID 0x%06x handle 0x%x role %s %s tgt %u\n"
3028 " WWNN 0x%08x%08x WWPN 0x%08x%08x";
4768 int bus;
4769 static const char prom[] = "Chan %d PortID 0x%06x handle 0x%x role %s %s WWPN 0x%08x%08x";
4770 static const char prom2[] = "Chan %d PortID 0x%06x handle 0x%x role %s %s tgt %u WWPN 0x%08x%08x";
3029 char *msg = NULL;
3030 target_id_t tgt;
3031 fcportdb_t *lp;
3032 struct cam_path *tmppath;
4771 char *msg = NULL;
4772 target_id_t tgt;
4773 fcportdb_t *lp;
4774 struct cam_path *tmppath;
4775 va_list ap;
3033
3034 switch (cmd) {
3035 case ISPASYNC_NEW_TGT_PARAMS:
3036 {
4776
4777 switch (cmd) {
4778 case ISPASYNC_NEW_TGT_PARAMS:
4779 {
3037#ifdef CAM_NEW_TRAN_CODE
3038 struct ccb_trans_settings_scsi *scsi;
3039 struct ccb_trans_settings_spi *spi;
4780 struct ccb_trans_settings_scsi *scsi;
4781 struct ccb_trans_settings_spi *spi;
3040#endif
3041 int flags, tgt;
4782 int flags, tgt;
3042 sdparam *sdp = isp->isp_param;
4783 sdparam *sdp;
3043 struct ccb_trans_settings cts;
3044
3045 memset(&cts, 0, sizeof (struct ccb_trans_settings));
3046
4784 struct ccb_trans_settings cts;
4785
4786 memset(&cts, 0, sizeof (struct ccb_trans_settings));
4787
3047 tgt = *((int *)arg);
3048 bus = (tgt >> 16) & 0xffff;
3049 tgt &= 0xffff;
3050 sdp += bus;
3051 if (xpt_create_path(&tmppath, NULL,
3052 cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim),
3053 tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
3054 isp_prt(isp, ISP_LOGWARN,
3055 "isp_async cannot make temp path for %d.%d",
3056 tgt, bus);
3057 rv = -1;
4788 va_start(ap, cmd);
4789 bus = va_arg(ap, int);
4790 tgt = va_arg(ap, int);
4791 va_end(ap);
4792 sdp = SDPARAM(isp, bus);
4793
4794 if (xpt_create_path(&tmppath, NULL, cam_sim_path(ISP_SPI_PC(isp, bus)->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
4795 isp_prt(isp, ISP_LOGWARN, "isp_async cannot make temp path for %d.%d", tgt, bus);
3058 break;
3059 }
3060 flags = sdp->isp_devparam[tgt].actv_flags;
4796 break;
4797 }
4798 flags = sdp->isp_devparam[tgt].actv_flags;
3061#ifdef CAM_NEW_TRAN_CODE
3062 cts.type = CTS_TYPE_CURRENT_SETTINGS;
3063 cts.protocol = PROTO_SCSI;
3064 cts.transport = XPORT_SPI;
3065
3066 scsi = &cts.proto_specific.scsi;
3067 spi = &cts.xport_specific.spi;
3068
3069 if (flags & DPARM_TQING) {

--- 12 unchanged lines hidden (view full) ---

3082 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
3083 }
3084 if (flags & DPARM_SYNC) {
3085 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3086 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3087 spi->sync_period = sdp->isp_devparam[tgt].actv_period;
3088 spi->sync_offset = sdp->isp_devparam[tgt].actv_offset;
3089 }
4799 cts.type = CTS_TYPE_CURRENT_SETTINGS;
4800 cts.protocol = PROTO_SCSI;
4801 cts.transport = XPORT_SPI;
4802
4803 scsi = &cts.proto_specific.scsi;
4804 spi = &cts.xport_specific.spi;
4805
4806 if (flags & DPARM_TQING) {

--- 12 unchanged lines hidden (view full) ---

4819 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
4820 }
4821 if (flags & DPARM_SYNC) {
4822 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
4823 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
4824 spi->sync_period = sdp->isp_devparam[tgt].actv_period;
4825 spi->sync_offset = sdp->isp_devparam[tgt].actv_offset;
4826 }
3090#else
3091 cts.flags = CCB_TRANS_CURRENT_SETTINGS;
3092 cts.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
3093 if (flags & DPARM_DISC) {
3094 cts.flags |= CCB_TRANS_DISC_ENB;
3095 }
3096 if (flags & DPARM_TQING) {
3097 cts.flags |= CCB_TRANS_TAG_ENB;
3098 }
3099 cts.valid |= CCB_TRANS_BUS_WIDTH_VALID;
3100 cts.bus_width = (flags & DPARM_WIDE)?
3101 MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT;
3102 cts.sync_period = sdp->isp_devparam[tgt].actv_period;
3103 cts.sync_offset = sdp->isp_devparam[tgt].actv_offset;
3104 if (flags & DPARM_SYNC) {
3105 cts.valid |=
3106 CCB_TRANS_SYNC_RATE_VALID |
3107 CCB_TRANS_SYNC_OFFSET_VALID;
3108 }
3109#endif
3110 isp_prt(isp, ISP_LOGDEBUG2,
3111 "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x",
3112 bus, tgt, sdp->isp_devparam[tgt].actv_period,
3113 sdp->isp_devparam[tgt].actv_offset, flags);
4827 isp_prt(isp, ISP_LOGDEBUG2, "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x", bus, tgt, sdp->isp_devparam[tgt].actv_period, sdp->isp_devparam[tgt].actv_offset, flags);
3114 xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
3115 xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
3116 xpt_free_path(tmppath);
3117 break;
3118 }
3119 case ISPASYNC_BUS_RESET:
4828 xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
4829 xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
4830 xpt_free_path(tmppath);
4831 break;
4832 }
4833 case ISPASYNC_BUS_RESET:
3120 bus = *((int *)arg);
3121 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected",
3122 bus);
3123 if (bus > 0 && isp->isp_path2) {
3124 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
3125 } else if (isp->isp_path) {
3126 xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
4834 {
4835 va_start(ap, cmd);
4836 bus = va_arg(ap, int);
4837 va_end(ap);
4838 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected", bus);
4839 if (IS_FC(isp)) {
4840 xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, NULL);
4841 } else {
4842 xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, NULL);
3127 }
3128 break;
4843 }
4844 break;
4845 }
3129 case ISPASYNC_LIP:
3130 if (msg == NULL) {
3131 msg = "LIP Received";
3132 }
3133 /* FALLTHROUGH */
3134 case ISPASYNC_LOOP_RESET:
3135 if (msg == NULL) {
3136 msg = "LOOP Reset";
3137 }
3138 /* FALLTHROUGH */
3139 case ISPASYNC_LOOP_DOWN:
4846 case ISPASYNC_LIP:
4847 if (msg == NULL) {
4848 msg = "LIP Received";
4849 }
4850 /* FALLTHROUGH */
4851 case ISPASYNC_LOOP_RESET:
4852 if (msg == NULL) {
4853 msg = "LOOP Reset";
4854 }
4855 /* FALLTHROUGH */
4856 case ISPASYNC_LOOP_DOWN:
4857 {
4858 struct isp_fc *fc;
3140 if (msg == NULL) {
3141 msg = "LOOP Down";
3142 }
4859 if (msg == NULL) {
4860 msg = "LOOP Down";
4861 }
3143 if (isp->isp_path) {
3144 isp_freeze_loopdown(isp, msg);
4862 va_start(ap, cmd);
4863 bus = va_arg(ap, int);
4864 va_end(ap);
4865
4866 FCPARAM(isp, bus)->link_active = 1;
4867
4868 fc = ISP_FC_PC(isp, bus);
4869 /*
4870 * We don't do any simq freezing if we are only in target mode
4871 */
4872 if (fc->role & ISP_ROLE_INITIATOR) {
4873 if (fc->path) {
4874 isp_freeze_loopdown(isp, bus, msg);
4875 }
4876 if (fc->ldt_running == 0) {
4877 fc->ldt_running = 1;
4878 callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc);
4879 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "starting Loop Down Timer @ %lu", (unsigned long) time_uptime);
4880 }
3145 }
4881 }
3146 if (isp->isp_osinfo.ldt_running == 0) {
3147 isp->isp_osinfo.ldt_running = 1;
3148 callout_reset(&isp->isp_osinfo.ldt,
3149 isp->isp_osinfo.loop_down_limit * hz, isp_ldt, isp);
3150 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3151 "starting Loop Down Timer");
3152 }
3153 isp_prt(isp, ISP_LOGINFO, msg);
4882 isp_prt(isp, ISP_LOGINFO, "Chan %d: %s", bus, msg);
3154 break;
4883 break;
4884 }
3155 case ISPASYNC_LOOP_UP:
4885 case ISPASYNC_LOOP_UP:
4886 va_start(ap, cmd);
4887 bus = va_arg(ap, int);
4888 va_end(ap);
3156 /*
3157 * Now we just note that Loop has come up. We don't
3158 * actually do anything because we're waiting for a
3159 * Change Notify before activating the FC cleanup
3160 * thread to look at the state of the loop again.
3161 */
4889 /*
4890 * Now we just note that Loop has come up. We don't
4891 * actually do anything because we're waiting for a
4892 * Change Notify before activating the FC cleanup
4893 * thread to look at the state of the loop again.
4894 */
3162 isp_prt(isp, ISP_LOGINFO, "Loop UP");
4895 FCPARAM(isp, bus)->link_active = 1;
4896 ISP_FC_PC(isp, bus)->loop_dead = 0;
4897 ISP_FC_PC(isp, bus)->loop_down_time = 0;
4898 isp_prt(isp, ISP_LOGINFO, "Chan %d Loop UP", bus);
3163 break;
3164 case ISPASYNC_DEV_ARRIVED:
4899 break;
4900 case ISPASYNC_DEV_ARRIVED:
3165 lp = arg;
4901 va_start(ap, cmd);
4902 bus = va_arg(ap, int);
4903 lp = va_arg(ap, fcportdb_t *);
4904 va_end(ap);
3166 lp->reserved = 0;
4905 lp->reserved = 0;
3167 if ((isp->isp_role & ISP_ROLE_INITIATOR) &&
3168 (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
3169 int dbidx = lp - FCPARAM(isp)->portdb;
4906 if ((ISP_FC_PC(isp, bus)->role & ISP_ROLE_INITIATOR) && (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
4907 int dbidx = lp - FCPARAM(isp, bus)->portdb;
3170 int i;
3171
3172 for (i = 0; i < MAX_FC_TARG; i++) {
3173 if (i >= FL_ID && i <= SNS_ID) {
3174 continue;
3175 }
4908 int i;
4909
4910 for (i = 0; i < MAX_FC_TARG; i++) {
4911 if (i >= FL_ID && i <= SNS_ID) {
4912 continue;
4913 }
3176 if (FCPARAM(isp)->isp_ini_map[i] == 0) {
4914 if (FCPARAM(isp, bus)->isp_dev_map[i] == 0) {
3177 break;
3178 }
3179 }
3180 if (i < MAX_FC_TARG) {
4915 break;
4916 }
4917 }
4918 if (i < MAX_FC_TARG) {
3181 FCPARAM(isp)->isp_ini_map[i] = dbidx + 1;
3182 lp->ini_map_idx = i + 1;
4919 FCPARAM(isp, bus)->isp_dev_map[i] = dbidx + 1;
4920 lp->dev_map_idx = i + 1;
3183 } else {
3184 isp_prt(isp, ISP_LOGWARN, "out of target ids");
4921 } else {
4922 isp_prt(isp, ISP_LOGWARN, "out of target ids");
3185 isp_dump_portdb(isp);
4923 isp_dump_portdb(isp, bus);
3186 }
3187 }
4924 }
4925 }
3188 if (lp->ini_map_idx) {
3189 tgt = lp->ini_map_idx - 1;
3190 isp_prt(isp, ISP_LOGCONFIG, prom2,
3191 lp->portid, lp->handle,
3192 roles[lp->roles], "arrived at", tgt,
3193 (uint32_t) (lp->node_wwn >> 32),
3194 (uint32_t) lp->node_wwn,
3195 (uint32_t) (lp->port_wwn >> 32),
3196 (uint32_t) lp->port_wwn);
3197 isp_make_here(isp, tgt);
4926 if (lp->dev_map_idx) {
4927 tgt = lp->dev_map_idx - 1;
4928 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, roles[lp->roles], "arrived at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
4929 isp_make_here(isp, bus, tgt);
3198 } else {
4930 } else {
3199 isp_prt(isp, ISP_LOGCONFIG, prom,
3200 lp->portid, lp->handle,
3201 roles[lp->roles], "arrived",
3202 (uint32_t) (lp->node_wwn >> 32),
3203 (uint32_t) lp->node_wwn,
3204 (uint32_t) (lp->port_wwn >> 32),
3205 (uint32_t) lp->port_wwn);
4931 isp_prt(isp, ISP_LOGCONFIG, prom, bus, lp->portid, lp->handle, roles[lp->roles], "arrived", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
3206 }
3207 break;
3208 case ISPASYNC_DEV_CHANGED:
4932 }
4933 break;
4934 case ISPASYNC_DEV_CHANGED:
3209 lp = arg;
4935 va_start(ap, cmd);
4936 bus = va_arg(ap, int);
4937 lp = va_arg(ap, fcportdb_t *);
4938 va_end(ap);
4939 lp->reserved = 0;
3210 if (isp_change_is_bad) {
3211 lp->state = FC_PORTDB_STATE_NIL;
4940 if (isp_change_is_bad) {
4941 lp->state = FC_PORTDB_STATE_NIL;
3212 if (lp->ini_map_idx) {
3213 tgt = lp->ini_map_idx - 1;
3214 FCPARAM(isp)->isp_ini_map[tgt] = 0;
3215 lp->ini_map_idx = 0;
3216 isp_prt(isp, ISP_LOGCONFIG, prom3,
3217 lp->portid, tgt, "change is bad");
3218 isp_make_gone(isp, tgt);
4942 if (lp->dev_map_idx) {
4943 tgt = lp->dev_map_idx - 1;
4944 FCPARAM(isp, bus)->isp_dev_map[tgt] = 0;
4945 lp->dev_map_idx = 0;
4946 isp_prt(isp, ISP_LOGCONFIG, prom3, bus, lp->portid, tgt, "change is bad");
4947 isp_make_gone(isp, bus, tgt);
3219 } else {
4948 } else {
3220 isp_prt(isp, ISP_LOGCONFIG, prom,
3221 lp->portid, lp->handle,
3222 roles[lp->roles],
3223 "changed and departed",
3224 (uint32_t) (lp->node_wwn >> 32),
3225 (uint32_t) lp->node_wwn,
3226 (uint32_t) (lp->port_wwn >> 32),
3227 (uint32_t) lp->port_wwn);
4949 isp_prt(isp, ISP_LOGCONFIG, prom, bus, lp->portid, lp->handle, roles[lp->roles], "changed and departed",
4950 (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
3228 }
3229 } else {
3230 lp->portid = lp->new_portid;
3231 lp->roles = lp->new_roles;
4951 }
4952 } else {
4953 lp->portid = lp->new_portid;
4954 lp->roles = lp->new_roles;
3232 if (lp->ini_map_idx) {
3233 int t = lp->ini_map_idx - 1;
3234 FCPARAM(isp)->isp_ini_map[t] =
3235 (lp - FCPARAM(isp)->portdb) + 1;
3236 tgt = lp->ini_map_idx - 1;
3237 isp_prt(isp, ISP_LOGCONFIG, prom2,
3238 lp->portid, lp->handle,
3239 roles[lp->roles], "changed at", tgt,
3240 (uint32_t) (lp->node_wwn >> 32),
3241 (uint32_t) lp->node_wwn,
3242 (uint32_t) (lp->port_wwn >> 32),
3243 (uint32_t) lp->port_wwn);
4955 if (lp->dev_map_idx) {
4956 int t = lp->dev_map_idx - 1;
4957 FCPARAM(isp, bus)->isp_dev_map[t] = (lp - FCPARAM(isp, bus)->portdb) + 1;
4958 tgt = lp->dev_map_idx - 1;
4959 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, roles[lp->roles], "changed at", tgt,
4960 (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
3244 } else {
4961 } else {
3245 isp_prt(isp, ISP_LOGCONFIG, prom,
3246 lp->portid, lp->handle,
3247 roles[lp->roles], "changed",
3248 (uint32_t) (lp->node_wwn >> 32),
3249 (uint32_t) lp->node_wwn,
3250 (uint32_t) (lp->port_wwn >> 32),
3251 (uint32_t) lp->port_wwn);
4962 isp_prt(isp, ISP_LOGCONFIG, prom, bus, lp->portid, lp->handle, roles[lp->roles], "changed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
3252 }
3253 }
3254 break;
3255 case ISPASYNC_DEV_STAYED:
4963 }
4964 }
4965 break;
4966 case ISPASYNC_DEV_STAYED:
3256 lp = arg;
3257 if (lp->ini_map_idx) {
3258 tgt = lp->ini_map_idx - 1;
3259 isp_prt(isp, ISP_LOGCONFIG, prom2,
3260 lp->portid, lp->handle,
3261 roles[lp->roles], "stayed at", tgt,
3262 (uint32_t) (lp->node_wwn >> 32),
3263 (uint32_t) lp->node_wwn,
3264 (uint32_t) (lp->port_wwn >> 32),
3265 (uint32_t) lp->port_wwn);
4967 va_start(ap, cmd);
4968 bus = va_arg(ap, int);
4969 lp = va_arg(ap, fcportdb_t *);
4970 va_end(ap);
4971 if (lp->dev_map_idx) {
4972 tgt = lp->dev_map_idx - 1;
4973 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, roles[lp->roles], "stayed at", tgt,
4974 (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
3266 } else {
4975 } else {
3267 isp_prt(isp, ISP_LOGCONFIG, prom,
3268 lp->portid, lp->handle,
3269 roles[lp->roles], "stayed",
3270 (uint32_t) (lp->node_wwn >> 32),
3271 (uint32_t) lp->node_wwn,
3272 (uint32_t) (lp->port_wwn >> 32),
3273 (uint32_t) lp->port_wwn);
4976 isp_prt(isp, ISP_LOGCONFIG, prom, bus, lp->portid, lp->handle, roles[lp->roles], "stayed",
4977 (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
3274 }
3275 break;
3276 case ISPASYNC_DEV_GONE:
4978 }
4979 break;
4980 case ISPASYNC_DEV_GONE:
3277 lp = arg;
4981 va_start(ap, cmd);
4982 bus = va_arg(ap, int);
4983 lp = va_arg(ap, fcportdb_t *);
4984 va_end(ap);
3278 /*
3279 * If this has a virtual target and we haven't marked it
3280 * that we're going to have isp_gdt tell the OS it's gone,
3281 * set the isp_gdt timer running on it.
3282 *
3283 * If it isn't marked that isp_gdt is going to get rid of it,
3284 * announce that it's gone.
3285 */
4985 /*
4986 * If this has a virtual target and we haven't marked it
4987 * that we're going to have isp_gdt tell the OS it's gone,
4988 * set the isp_gdt timer running on it.
4989 *
4990 * If it isn't marked that isp_gdt is going to get rid of it,
4991 * announce that it's gone.
4992 */
3286 if (lp->ini_map_idx && lp->reserved == 0) {
4993 if (lp->dev_map_idx && lp->reserved == 0) {
3287 lp->reserved = 1;
4994 lp->reserved = 1;
3288 lp->new_reserved = isp->isp_osinfo.gone_device_time;
4995 lp->new_reserved = ISP_FC_PC(isp, bus)->gone_device_time;
3289 lp->state = FC_PORTDB_STATE_ZOMBIE;
4996 lp->state = FC_PORTDB_STATE_ZOMBIE;
3290 if (isp->isp_osinfo.gdt_running == 0) {
3291 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3292 "starting Gone Device Timer");
3293 isp->isp_osinfo.gdt_running = 1;
3294 callout_reset(&isp->isp_osinfo.gdt, hz,
3295 isp_gdt, isp);
4997 if (ISP_FC_PC(isp, bus)->gdt_running == 0) {
4998 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d starting Gone Device Timer", bus);
4999 ISP_FC_PC(isp, bus)->gdt_running = 1;
5000 callout_reset(&ISP_FC_PC(isp, bus)->gdt, hz, isp_gdt, ISP_FC_PC(isp, bus));
3296 }
5001 }
3297 tgt = lp->ini_map_idx - 1;
3298 isp_prt(isp, ISP_LOGCONFIG, prom2,
3299 lp->portid, lp->handle,
3300 roles[lp->roles], "gone zombie at", tgt,
3301 (uint32_t) (lp->node_wwn >> 32),
3302 (uint32_t) lp->node_wwn,
3303 (uint32_t) (lp->port_wwn >> 32),
3304 (uint32_t) lp->port_wwn);
5002 tgt = lp->dev_map_idx - 1;
5003 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, roles[lp->roles], "gone zombie at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
3305 } else if (lp->reserved == 0) {
5004 } else if (lp->reserved == 0) {
3306 isp_prt(isp, ISP_LOGCONFIG, prom,
3307 lp->portid, lp->handle,
3308 roles[lp->roles], "departed",
3309 (uint32_t) (lp->node_wwn >> 32),
3310 (uint32_t) lp->node_wwn,
3311 (uint32_t) (lp->port_wwn >> 32),
3312 (uint32_t) lp->port_wwn);
5005 isp_prt(isp, ISP_LOGCONFIG, prom, bus, lp->portid, lp->handle, roles[lp->roles], "departed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
3313 }
3314 break;
3315 case ISPASYNC_CHANGE_NOTIFY:
3316 {
3317 char *msg;
5006 }
5007 break;
5008 case ISPASYNC_CHANGE_NOTIFY:
5009 {
5010 char *msg;
3318 if (arg == ISPASYNC_CHANGE_PDB) {
3319 msg = "Port Database Changed";
3320 } else if (arg == ISPASYNC_CHANGE_SNS) {
3321 msg = "Name Server Database Changed";
5011 int evt, nphdl, nlstate, reason;
5012
5013 va_start(ap, cmd);
5014 bus = va_arg(ap, int);
5015 evt = va_arg(ap, int);
5016 if (IS_24XX(isp) && evt == ISPASYNC_CHANGE_PDB) {
5017 nphdl = va_arg(ap, int);
5018 nlstate = va_arg(ap, int);
5019 reason = va_arg(ap, int);
3322 } else {
5020 } else {
3323 msg = "Other Change Notify";
5021 nphdl = NIL_HANDLE;
5022 nlstate = reason = 0;
3324 }
5023 }
5024 va_end(ap);
5025
5026 if (evt == ISPASYNC_CHANGE_PDB) {
5027 msg = "Chan %d Port Database Changed";
5028 } else if (evt == ISPASYNC_CHANGE_SNS) {
5029 msg = "Chan %d Name Server Database Changed";
5030 } else {
5031 msg = "Chan %d Other Change Notify";
5032 }
5033
3325 /*
3326 * If the loop down timer is running, cancel it.
3327 */
5034 /*
5035 * If the loop down timer is running, cancel it.
5036 */
3328 if (isp->isp_osinfo.ldt_running) {
3329 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3330 "Stopping Loop Down Timer");
3331 isp->isp_osinfo.ldt_running = 0;
3332 callout_stop(&isp->isp_osinfo.ldt);
5037 if (ISP_FC_PC(isp, bus)->ldt_running) {
5038 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Stopping Loop Down Timer @ %lu", (unsigned long) time_uptime);
5039 ISP_FC_PC(isp, bus)->ldt_running = 0;
5040 callout_stop(&ISP_FC_PC(isp, bus)->ldt);
3333 }
5041 }
3334 isp_prt(isp, ISP_LOGINFO, msg);
3335 isp_freeze_loopdown(isp, msg);
3336 wakeup(ISP_KT_WCHAN(isp));
5042 isp_prt(isp, ISP_LOGINFO, msg, bus);
5043 if (ISP_FC_PC(isp, bus)->role & ISP_ROLE_INITIATOR) {
5044 isp_freeze_loopdown(isp, bus, msg);
5045 }
5046 wakeup(ISP_FC_PC(isp, bus));
3337 break;
3338 }
3339#ifdef ISP_TARGET_MODE
3340 case ISPASYNC_TARGET_NOTIFY:
3341 {
5047 break;
5048 }
5049#ifdef ISP_TARGET_MODE
5050 case ISPASYNC_TARGET_NOTIFY:
5051 {
3342 tmd_notify_t *nt = arg;
3343 isp_prt(isp, ISP_LOGALL,
3344 "target notify code 0x%x", nt->nt_ncode);
5052 isp_notify_t *notify;
5053 va_start(ap, cmd);
5054 notify = va_arg(ap, isp_notify_t *);
5055 va_end(ap);
5056 switch (notify->nt_ncode) {
5057 case NT_ABORT_TASK:
5058 case NT_ABORT_TASK_SET:
5059 case NT_CLEAR_ACA:
5060 case NT_CLEAR_TASK_SET:
5061 case NT_LUN_RESET:
5062 case NT_TARGET_RESET:
5063 /*
5064 * These are task management functions.
5065 */
5066 isp_handle_platform_target_tmf(isp, notify);
5067 break;
5068 case NT_BUS_RESET:
5069 case NT_LIP_RESET:
5070 case NT_LINK_UP:
5071 case NT_LINK_DOWN:
5072 /*
5073 * No action need be taken here.
5074 */
5075 break;
5076 case NT_HBA_RESET:
5077 isp_del_all_wwn_entries(isp, ISP_NOCHAN);
5078 break;
5079 case NT_LOGOUT:
5080 /*
5081 * This is device arrival/departure notification
5082 */
5083 isp_handle_platform_target_notify_ack(isp, notify);
5084 break;
5085 case NT_ARRIVED:
5086 {
5087 struct ac_contract ac;
5088 struct ac_device_changed *fc;
5089
5090 ac.contract_number = AC_CONTRACT_DEV_CHG;
5091 fc = (struct ac_device_changed *) ac.contract_data;
5092 fc->wwpn = notify->nt_wwn;
5093 fc->port = notify->nt_sid;
5094 fc->target = notify->nt_nphdl;
5095 fc->arrived = 1;
5096 xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac);
5097 break;
5098 }
5099 case NT_DEPARTED:
5100 {
5101 struct ac_contract ac;
5102 struct ac_device_changed *fc;
5103
5104 ac.contract_number = AC_CONTRACT_DEV_CHG;
5105 fc = (struct ac_device_changed *) ac.contract_data;
5106 fc->wwpn = notify->nt_wwn;
5107 fc->port = notify->nt_sid;
5108 fc->target = notify->nt_nphdl;
5109 fc->arrived = 0;
5110 xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac);
5111 break;
5112 }
5113 default:
5114 isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode);
5115 isp_handle_platform_target_notify_ack(isp, notify);
5116 break;
5117 }
3345 break;
3346 }
3347 case ISPASYNC_TARGET_ACTION:
5118 break;
5119 }
5120 case ISPASYNC_TARGET_ACTION:
3348 switch (((isphdr_t *)arg)->rqs_entry_type) {
5121 {
5122 isphdr_t *hp;
5123
5124 va_start(ap, cmd);
5125 hp = va_arg(ap, isphdr_t *);
5126 va_end(ap);
5127 switch (hp->rqs_entry_type) {
3349 default:
5128 default:
3350 isp_prt(isp, ISP_LOGWARN,
3351 "event 0x%x for unhandled target action",
3352 ((isphdr_t *)arg)->rqs_entry_type);
5129 isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x", __func__, hp->rqs_entry_type);
3353 break;
3354 case RQSTYPE_NOTIFY:
3355 if (IS_SCSI(isp)) {
5130 break;
5131 case RQSTYPE_NOTIFY:
5132 if (IS_SCSI(isp)) {
3356 rv = isp_handle_platform_notify_scsi(isp,
3357 (in_entry_t *) arg);
5133 isp_handle_platform_notify_scsi(isp, (in_entry_t *) hp);
5134 } else if (IS_24XX(isp)) {
5135 isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp);
3358 } else {
5136 } else {
3359 rv = isp_handle_platform_notify_fc(isp,
3360 (in_fcentry_t *) arg);
5137 isp_handle_platform_notify_fc(isp, (in_fcentry_t *) hp);
3361 }
3362 break;
3363 case RQSTYPE_ATIO:
5138 }
5139 break;
5140 case RQSTYPE_ATIO:
3364 rv = isp_handle_platform_atio(isp, (at_entry_t *) arg);
5141 if (IS_24XX(isp)) {
5142 isp_handle_platform_atio7(isp, (at7_entry_t *) hp);
5143 } else {
5144 isp_handle_platform_atio(isp, (at_entry_t *) hp);
5145 }
3365 break;
3366 case RQSTYPE_ATIO2:
5146 break;
5147 case RQSTYPE_ATIO2:
3367 rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg);
5148 isp_handle_platform_atio2(isp, (at2_entry_t *) hp);
3368 break;
5149 break;
5150 case RQSTYPE_CTIO7:
3369 case RQSTYPE_CTIO3:
3370 case RQSTYPE_CTIO2:
3371 case RQSTYPE_CTIO:
5151 case RQSTYPE_CTIO3:
5152 case RQSTYPE_CTIO2:
5153 case RQSTYPE_CTIO:
3372 rv = isp_handle_platform_ctio(isp, arg);
5154 isp_handle_platform_ctio(isp, hp);
3373 break;
5155 break;
5156 case RQSTYPE_ABTS_RCVD:
5157 {
5158 abts_t *abts = (abts_t *)hp;
5159 isp_notify_t notify, *nt = &notify;
5160 tstate_t *tptr;
5161 fcportdb_t *lp;
5162 uint16_t chan;
5163 uint32_t sid, did;
5164
5165 did = (abts->abts_did_hi << 16) | abts->abts_did_lo;
5166 sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo;
5167 ISP_MEMZERO(nt, sizeof (isp_notify_t));
5168
5169 nt->nt_hba = isp;
5170 nt->nt_did = did;
5171 nt->nt_nphdl = abts->abts_nphdl;
5172 nt->nt_sid = sid;
5173 isp_find_chan_by_did(isp, did, &chan);
5174 if (chan == ISP_NOCHAN) {
5175 nt->nt_tgt = TGT_ANY;
5176 } else {
5177 nt->nt_tgt = FCPARAM(isp, chan)->isp_wwpn;
5178 if (isp_find_pdb_by_loopid(isp, chan, abts->abts_nphdl, &lp)) {
5179 nt->nt_wwn = lp->port_wwn;
5180 } else {
5181 nt->nt_wwn = INI_ANY;
5182 }
5183 }
5184 /*
5185 * Try hard to find the lun for this command.
5186 */
5187 tptr = get_lun_statep_from_tag(isp, chan, abts->abts_rxid_task);
5188 if (tptr) {
5189 nt->nt_lun = xpt_path_lun_id(tptr->owner);
5190 rls_lun_statep(isp, tptr);
5191 } else {
5192 nt->nt_lun = LUN_ANY;
5193 }
5194 nt->nt_need_ack = 1;
5195 nt->nt_tagval = abts->abts_rxid_task;
5196 nt->nt_tagval |= (((uint64_t) abts->abts_rxid_abts) << 32);
5197 if (abts->abts_rxid_task == ISP24XX_NO_TASK) {
5198 isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS from N-Port handle 0x%x Port 0x%06x has no task id (rx_id 0x%04x ox_id 0x%04x)",
5199 abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rx_id, abts->abts_ox_id);
5200 } else {
5201 isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS from N-Port handle 0x%x Port 0x%06x for task 0x%x (rx_id 0x%04x ox_id 0x%04x)",
5202 abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rxid_task, abts->abts_rx_id, abts->abts_ox_id);
5203 }
5204 nt->nt_channel = chan;
5205 nt->nt_ncode = NT_ABORT_TASK;
5206 nt->nt_lreserved = hp;
5207 isp_handle_platform_target_tmf(isp, nt);
5208 break;
5209 }
3374 case RQSTYPE_ENABLE_LUN:
3375 case RQSTYPE_MODIFY_LUN:
5210 case RQSTYPE_ENABLE_LUN:
5211 case RQSTYPE_MODIFY_LUN:
3376 isp_ledone(isp, (lun_entry_t *) arg);
5212 isp_ledone(isp, (lun_entry_t *) hp);
3377 break;
3378 }
3379 break;
5213 break;
5214 }
5215 break;
5216 }
3380#endif
3381 case ISPASYNC_FW_CRASH:
3382 {
3383 uint16_t mbox1, mbox6;
3384 mbox1 = ISP_READ(isp, OUTMAILBOX1);
3385 if (IS_DUALBUS(isp)) {
3386 mbox6 = ISP_READ(isp, OUTMAILBOX6);
3387 } else {
3388 mbox6 = 0;
3389 }
5217#endif
5218 case ISPASYNC_FW_CRASH:
5219 {
5220 uint16_t mbox1, mbox6;
5221 mbox1 = ISP_READ(isp, OUTMAILBOX1);
5222 if (IS_DUALBUS(isp)) {
5223 mbox6 = ISP_READ(isp, OUTMAILBOX6);
5224 } else {
5225 mbox6 = 0;
5226 }
3390 isp_prt(isp, ISP_LOGERR,
3391 "Internal Firmware Error on bus %d @ RISC Address 0x%x",
3392 mbox6, mbox1);
3393#ifdef ISP_FW_CRASH_DUMP
5227 isp_prt(isp, ISP_LOGERR, "Internal Firmware Error on bus %d @ RISC Address 0x%x", mbox6, mbox1);
3394 mbox1 = isp->isp_osinfo.mbox_sleep_ok;
3395 isp->isp_osinfo.mbox_sleep_ok = 0;
5228 mbox1 = isp->isp_osinfo.mbox_sleep_ok;
5229 isp->isp_osinfo.mbox_sleep_ok = 0;
3396 if (IS_FC(isp)) {
3397 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
3398 FCPARAM(isp)->isp_loopstate = LOOP_NIL;
3399 isp_freeze_loopdown(isp, "f/w crash");
3400 isp_fw_dump(isp);
3401 }
3402 isp_reinit(isp);
5230 isp_reinit(isp, 1);
3403 isp->isp_osinfo.mbox_sleep_ok = mbox1;
5231 isp->isp_osinfo.mbox_sleep_ok = mbox1;
3404#else
3405 mbox1 = isp->isp_osinfo.mbox_sleep_ok;
3406 isp->isp_osinfo.mbox_sleep_ok = 0;
3407 isp_reinit(isp);
3408 isp->isp_osinfo.mbox_sleep_ok = mbox1;
3409#endif
3410 isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
3411 break;
3412 }
5232 isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
5233 break;
5234 }
3413 case ISPASYNC_UNHANDLED_RESPONSE:
3414 break;
3415 default:
3416 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
3417 break;
3418 }
5235 default:
5236 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
5237 break;
5238 }
3419 return (rv);
3420}
3421
3422
3423/*
3424 * Locks are held before coming here.
3425 */
3426void
3427isp_uninit(ispsoftc_t *isp)
3428{
3429 if (IS_24XX(isp)) {
3430 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
3431 } else {
3432 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
3433 }
3434 ISP_DISABLE_INTS(isp);
3435}
3436
5239}
5240
5241
5242/*
5243 * Locks are held before coming here.
5244 */
5245void
5246isp_uninit(ispsoftc_t *isp)
5247{
5248 if (IS_24XX(isp)) {
5249 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
5250 } else {
5251 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
5252 }
5253 ISP_DISABLE_INTS(isp);
5254}
5255
5256/*
5257 * When we want to get the 'default' WWNs (when lacking NVRAM), we pick them
5258 * up from our platform default (defww{p|n}n) and morph them based upon
5259 * channel.
5260 *
5261 * When we want to get the 'active' WWNs, we get NVRAM WWNs and then morph them
5262 * based upon channel.
5263 */
5264
5265uint64_t
5266isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn)
5267{
5268 uint64_t seed;
5269 struct isp_fc *fc = ISP_FC_PC(isp, chan);
5270
5271 /*
5272 * If we're asking for a active WWN, the default overrides get
5273 * returned, otherwise the NVRAM value is picked.
5274 *
5275 * If we're asking for a default WWN, we just pick the default override.
5276 */
5277 if (isactive) {
5278 seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
5279 if (seed) {
5280 return (seed);
5281 }
5282 seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram : FCPARAM(isp, chan)->isp_wwpn_nvram;
5283 } else {
5284 seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
5285 }
5286
5287
5288 /*
5289 * For channel zero just return what we have. For either ACIIVE or
5290 * DEFAULT cases, we depend on default override of NVRAM values for
5291 * channel zero.
5292 */
5293 if (chan == 0) {
5294 return (seed);
5295 }
5296
5297 /*
5298 * For other channels, we are doing one of three things:
5299 *
5300 * 1. If what we have now is non-zero, return it. Otherwise we morph
5301 * values from channel 0. 2. If we're here for a WWPN we synthesize
5302 * it if Channel 0's wwpn has a type 2 NAA. 3. If we're here for a
5303 * WWNN we synthesize it if Channel 0's wwnn has a type 2 NAA.
5304 */
5305
5306 if (seed) {
5307 return (seed);
5308 }
5309 if (isactive) {
5310 seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram : FCPARAM(isp, 0)->isp_wwpn_nvram;
5311 } else {
5312 seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn : ISP_FC_PC(isp, 0)->def_wwpn;
5313 }
5314
5315 if (((seed >> 60) & 0xf) == 2) {
5316 /*
5317 * The type 2 NAA fields for QLogic cards appear be laid out
5318 * thusly:
5319 *
5320 * bits 63..60 NAA == 2 bits 59..57 unused/zero bit 56
5321 * port (1) or node (0) WWN distinguishor bit 48
5322 * physical port on dual-port chips (23XX/24XX)
5323 *
5324 * This is somewhat nutty, particularly since bit 48 is
5325 * irrelevant as they assign seperate serial numbers to
5326 * different physical ports anyway.
5327 *
5328 * We'll stick our channel number plus one first into bits
5329 * 57..59 and thence into bits 52..55 which allows for 8 bits
5330 * of channel which is comfortably more than our maximum
5331 * (126) now.
5332 */
5333 seed &= ~0x0FF0000000000000ULL;
5334 if (iswwnn == 0) {
5335 seed |= ((uint64_t) (chan + 1) & 0xf) << 56;
5336 seed |= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52;
5337 }
5338 } else {
5339 seed = 0;
5340 }
5341 return (seed);
5342}
5343
3437void
3438isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
3439{
3440 va_list ap;
3441 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
3442 return;
3443 }
3444 printf("%s: ", device_get_nameunit(isp->isp_dev));

--- 39 unchanged lines hidden (view full) ---

3484 max = isp->isp_mbxwrk0 + 1;
3485
3486 if (isp->isp_osinfo.mbox_sleep_ok) {
3487 unsigned int ms = (usecs + 999) / 1000;
3488
3489 isp->isp_osinfo.mbox_sleep_ok = 0;
3490 isp->isp_osinfo.mbox_sleeping = 1;
3491 for (olim = 0; olim < max; olim++) {
5344void
5345isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
5346{
5347 va_list ap;
5348 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
5349 return;
5350 }
5351 printf("%s: ", device_get_nameunit(isp->isp_dev));

--- 39 unchanged lines hidden (view full) ---

5391 max = isp->isp_mbxwrk0 + 1;
5392
5393 if (isp->isp_osinfo.mbox_sleep_ok) {
5394 unsigned int ms = (usecs + 999) / 1000;
5395
5396 isp->isp_osinfo.mbox_sleep_ok = 0;
5397 isp->isp_osinfo.mbox_sleeping = 1;
5398 for (olim = 0; olim < max; olim++) {
3492#if __FreeBSD_version < 700037
3493 tsleep(&isp->isp_mbxworkp, PRIBIO, "ispmbx_sleep",
3494 isp_mstohz(ms));
3495#else
3496 msleep(&isp->isp_mbxworkp, &isp->isp_osinfo.lock,
3497 PRIBIO, "ispmbx_sleep", isp_mstohz(ms));
3498#endif
5399 msleep(&isp->isp_mbxworkp, &isp->isp_osinfo.lock, PRIBIO, "ispmbx_sleep", isp_mstohz(ms));
3499 if (isp->isp_osinfo.mboxcmd_done) {
3500 break;
3501 }
3502 }
3503 isp->isp_osinfo.mbox_sleep_ok = 1;
3504 isp->isp_osinfo.mbox_sleeping = 0;
3505 } else {
3506 for (olim = 0; olim < max; olim++) {

--- 4 unchanged lines hidden (view full) ---

3511 break;
3512 }
3513 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
3514 isp_intr(isp, isr, sema, mbox);
3515 if (isp->isp_osinfo.mboxcmd_done) {
3516 break;
3517 }
3518 }
5400 if (isp->isp_osinfo.mboxcmd_done) {
5401 break;
5402 }
5403 }
5404 isp->isp_osinfo.mbox_sleep_ok = 1;
5405 isp->isp_osinfo.mbox_sleeping = 0;
5406 } else {
5407 for (olim = 0; olim < max; olim++) {

--- 4 unchanged lines hidden (view full) ---

5412 break;
5413 }
5414 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
5415 isp_intr(isp, isr, sema, mbox);
5416 if (isp->isp_osinfo.mboxcmd_done) {
5417 break;
5418 }
5419 }
3519 USEC_DELAY(100);
5420 ISP_DELAY(100);
3520 }
3521 if (isp->isp_osinfo.mboxcmd_done) {
3522 break;
3523 }
3524 }
3525 }
3526 if (isp->isp_osinfo.mboxcmd_done == 0) {
5421 }
5422 if (isp->isp_osinfo.mboxcmd_done) {
5423 break;
5424 }
5425 }
5426 }
5427 if (isp->isp_osinfo.mboxcmd_done == 0) {
3527 isp_prt(isp, ISP_LOGWARN,
3528 "%s Mailbox Command (0x%x) Timeout (%uus)",
3529 isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled",
3530 isp->isp_lastmbxcmd, usecs);
5428 isp_prt(isp, ISP_LOGWARN, "%s Mailbox Command (0x%x) Timeout (%uus) (started @ %s:%d)",
5429 isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled", isp->isp_lastmbxcmd, usecs, mbp->func, mbp->lineno);
3531 mbp->param[0] = MBOX_TIMEOUT;
3532 isp->isp_osinfo.mboxcmd_done = 1;
3533 }
3534}
3535
3536void
3537isp_mbox_notify_done(ispsoftc_t *isp)
3538{

--- 5 unchanged lines hidden (view full) ---

3544
3545void
3546isp_mbox_release(ispsoftc_t *isp)
3547{
3548 isp->isp_osinfo.mboxbsy = 0;
3549}
3550
3551int
5430 mbp->param[0] = MBOX_TIMEOUT;
5431 isp->isp_osinfo.mboxcmd_done = 1;
5432 }
5433}
5434
5435void
5436isp_mbox_notify_done(ispsoftc_t *isp)
5437{

--- 5 unchanged lines hidden (view full) ---

5443
5444void
5445isp_mbox_release(ispsoftc_t *isp)
5446{
5447 isp->isp_osinfo.mboxbsy = 0;
5448}
5449
5450int
5451isp_fc_scratch_acquire(ispsoftc_t *isp, int chan)
5452{
5453 int ret = 0;
5454 if (isp->isp_osinfo.pc.fc[chan].fcbsy) {
5455 ret = -1;
5456 } else {
5457 isp->isp_osinfo.pc.fc[chan].fcbsy = 1;
5458 }
5459 return (ret);
5460}
5461
5462int
3552isp_mstohz(int ms)
3553{
3554 int hz;
3555 struct timeval t;
3556 t.tv_sec = ms / 1000;
3557 t.tv_usec = (ms % 1000) * 1000;
3558 hz = tvtohz(&t);
3559 if (hz < 0) {

--- 21 unchanged lines hidden (view full) ---

3581 }
3582 ISP_UNLOCK(isp);
3583}
3584
3585void
3586isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl)
3587{
3588 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
5463isp_mstohz(int ms)
5464{
5465 int hz;
5466 struct timeval t;
5467 t.tv_sec = ms / 1000;
5468 t.tv_usec = (ms % 1000) * 1000;
5469 hz = tvtohz(&t);
5470 if (hz < 0) {

--- 21 unchanged lines hidden (view full) ---

5492 }
5493 ISP_UNLOCK(isp);
5494}
5495
5496void
5497isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl)
5498{
5499 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
3589 bus_dmamap_sync(isp->isp_osinfo.dmat,
3590 PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTREAD);
5500 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTREAD);
3591 } else {
5501 } else {
3592 bus_dmamap_sync(isp->isp_osinfo.dmat,
3593 PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTWRITE);
5502 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTWRITE);
3594 }
3595 bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap);
3596}
5503 }
5504 bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap);
5505}
5506
5507void
5508isp_timer(void *arg)
5509{
5510 ispsoftc_t *isp = arg;
5511#ifdef ISP_TARGET_MODE
5512 isp_tmcmd_restart(isp);
5513#endif
5514 callout_reset(&isp->isp_osinfo.tmo, hz, isp_timer, isp);
5515}