Deleted Added
full compact
isp_target.c (172568) isp_target.c (196008)
1/*-
1/*-
2 * Copyright (c) 1997-2007 by Matthew Jacob
2 * Copyright (c) 1997-2009 by Matthew Jacob
3 * All rights reserved.
3 * All rights reserved.
4 *
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:
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 *
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
14 *
15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
26 */
27/*
28 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
29 */
30/*
31 * Bug fixes gratefully acknowledged from:
32 * Oded Kedem <oded@kashya.com>
33 */
34/*
35 * Include header file appropriate for platform we're building on.
36 */
37
38#ifdef __NetBSD__
39#include <dev/ic/isp_netbsd.h>
40#endif
41#ifdef __FreeBSD__
42#include <sys/cdefs.h>
27 */
28/*
29 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
30 */
31/*
32 * Bug fixes gratefully acknowledged from:
33 * Oded Kedem <oded@kashya.com>
34 */
35/*
36 * Include header file appropriate for platform we're building on.
37 */
38
39#ifdef __NetBSD__
40#include <dev/ic/isp_netbsd.h>
41#endif
42#ifdef __FreeBSD__
43#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/sys/dev/isp/isp_target.c 172568 2007-10-12 06:03:46Z kevlo $");
44__FBSDID("$FreeBSD: head/sys/dev/isp/isp_target.c 196008 2009-08-01 01:04:26Z mjacob $");
44#include <dev/isp/isp_freebsd.h>
45#endif
46#ifdef __OpenBSD__
47#include <dev/ic/isp_openbsd.h>
48#endif
49#ifdef __linux__
50#include "isp_linux.h"
51#endif
52
53#ifdef ISP_TARGET_MODE
45#include <dev/isp/isp_freebsd.h>
46#endif
47#ifdef __OpenBSD__
48#include <dev/ic/isp_openbsd.h>
49#endif
50#ifdef __linux__
51#include "isp_linux.h"
52#endif
53
54#ifdef ISP_TARGET_MODE
54static const char atiocope[] =
55 "ATIO returned for lun %d because it was in the middle of Bus Device Reset "
56 "on bus %d";
57static const char atior[] =
58 "ATIO returned on for lun %d on from loopid %d because a Bus Reset "
59 "occurred on bus %d";
55static const char atiocope[] = "ATIO returned for lun %d because it was in the middle of Bus Device Reset on bus %d";
56static const char atior[] = "ATIO returned on for lun %d on from loopid %d because a Bus Reset occurred on bus %d";
57static const char rqo[] = "%s: Request Queue Overflow";
60
61static void isp_got_msg(ispsoftc_t *, in_entry_t *);
62static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *);
63static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *);
64static void isp_handle_atio(ispsoftc_t *, at_entry_t *);
65static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
66static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
67static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
68static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *);
58
59static void isp_got_msg(ispsoftc_t *, in_entry_t *);
60static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *);
61static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *);
62static void isp_handle_atio(ispsoftc_t *, at_entry_t *);
63static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
64static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
65static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
66static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *);
67static void isp_handle_24xx_inotify(ispsoftc_t *, in_fcentry_24xx_t *);
69
70/*
71 * The Qlogic driver gets an interrupt to look at response queue entries.
72 * Some of these are status completions for initiatior mode commands, but
73 * if target mode is enabled, we get a whole wad of response queue entries
74 * to be handled here.
75 *
76 * Basically the split into 3 main groups: Lun Enable/Modification responses,

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

159#define nacke_fcp unp.nacke_fcp
160#define nack_24xx unp.nack_24xx
161#define abts unp.abts
162#define abts_rsp unp.abts_rsp
163#define els unp.els
164#define hdrp unp.hp
165 } unp;
166 uint8_t local[QENTRY_LEN];
68
69/*
70 * The Qlogic driver gets an interrupt to look at response queue entries.
71 * Some of these are status completions for initiatior mode commands, but
72 * if target mode is enabled, we get a whole wad of response queue entries
73 * to be handled here.
74 *
75 * Basically the split into 3 main groups: Lun Enable/Modification responses,

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

158#define nacke_fcp unp.nacke_fcp
159#define nack_24xx unp.nack_24xx
160#define abts unp.abts
161#define abts_rsp unp.abts_rsp
162#define els unp.els
163#define hdrp unp.hp
164 } unp;
165 uint8_t local[QENTRY_LEN];
166 uint16_t iid;
167 int bus, type, level, rval = 1;
167 int bus, type, level, rval = 1;
168 isp_notify_t notify;
168
169 type = isp_get_response_type(isp, (isphdr_t *)vptr);
170 unp.vp = vptr;
171
172 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
173
169
170 type = isp_get_response_type(isp, (isphdr_t *)vptr);
171 unp.vp = vptr;
172
173 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
174
174 switch(type) {
175 switch (type) {
175 case RQSTYPE_ATIO:
176 if (IS_24XX(isp)) {
177 int len;
178
179 isp_get_atio7(isp, at7iop, (at7_entry_t *) local);
180 at7iop = (at7_entry_t *) local;
181 /*
176 case RQSTYPE_ATIO:
177 if (IS_24XX(isp)) {
178 int len;
179
180 isp_get_atio7(isp, at7iop, (at7_entry_t *) local);
181 at7iop = (at7_entry_t *) local;
182 /*
182 * Check for and do something with commands whose IULEN
183 * extends past a singel queue entry.
183 * Check for and do something with commands whose
184 * IULEN extends past a single queue entry.
184 */
185 len = at7iop->at_ta_len & 0xfffff;
186 if (len > (QENTRY_LEN - 8)) {
187 len -= (QENTRY_LEN - 8);
185 */
186 len = at7iop->at_ta_len & 0xfffff;
187 if (len > (QENTRY_LEN - 8)) {
188 len -= (QENTRY_LEN - 8);
188 isp_prt(isp, ISP_LOGINFO,
189 "long IU length (%d) ignored", len);
189 isp_prt(isp, ISP_LOGINFO, "long IU length (%d) ignored", len);
190 while (len > 0) {
190 while (len > 0) {
191 *optrp = ISP_NXT_QENTRY(*optrp,
192 RESULT_QUEUE_LEN(isp));
191 *optrp = ISP_NXT_QENTRY(*optrp, RESULT_QUEUE_LEN(isp));
193 len -= QENTRY_LEN;
194 }
195 }
196 /*
197 * Check for a task management function
198 */
199 if (at7iop->at_cmnd.fcp_cmnd_task_management) {
200 isp_got_tmf_24xx(isp, at7iop);
201 break;
202 }
203 /*
204 * Just go straight to outer layer for this one.
205 */
192 len -= QENTRY_LEN;
193 }
194 }
195 /*
196 * Check for a task management function
197 */
198 if (at7iop->at_cmnd.fcp_cmnd_task_management) {
199 isp_got_tmf_24xx(isp, at7iop);
200 break;
201 }
202 /*
203 * Just go straight to outer layer for this one.
204 */
206 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
205 isp_async(isp, ISPASYNC_TARGET_ACTION, local);
207 } else {
208 isp_get_atio(isp, atiop, (at_entry_t *) local);
209 isp_handle_atio(isp, (at_entry_t *) local);
210 }
211 break;
212
213 case RQSTYPE_CTIO:
214 isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
215 isp_handle_ctio(isp, (ct_entry_t *) local);
216 break;
217
218 case RQSTYPE_ATIO2:
206 } else {
207 isp_get_atio(isp, atiop, (at_entry_t *) local);
208 isp_handle_atio(isp, (at_entry_t *) local);
209 }
210 break;
211
212 case RQSTYPE_CTIO:
213 isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
214 isp_handle_ctio(isp, (ct_entry_t *) local);
215 break;
216
217 case RQSTYPE_ATIO2:
219 if (FCPARAM(isp)->isp_2klogin) {
218 if (ISP_CAP_2KLOGIN(isp)) {
220 isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
221 } else {
222 isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
223 }
224 isp_handle_atio2(isp, (at2_entry_t *) local);
225 break;
226
227 case RQSTYPE_CTIO3:
228 case RQSTYPE_CTIO2:
219 isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
220 } else {
221 isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
222 }
223 isp_handle_atio2(isp, (at2_entry_t *) local);
224 break;
225
226 case RQSTYPE_CTIO3:
227 case RQSTYPE_CTIO2:
229 if (FCPARAM(isp)->isp_2klogin) {
228 if (ISP_CAP_2KLOGIN(isp)) {
230 isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
231 } else {
232 isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
233 }
234 isp_handle_ctio2(isp, (ct2_entry_t *) local);
235 break;
236
237 case RQSTYPE_CTIO7:
238 isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local);
239 isp_handle_ctio7(isp, (ct7_entry_t *) local);
240 break;
241
242 case RQSTYPE_ENABLE_LUN:
243 case RQSTYPE_MODIFY_LUN:
244 isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
229 isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
230 } else {
231 isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
232 }
233 isp_handle_ctio2(isp, (ct2_entry_t *) local);
234 break;
235
236 case RQSTYPE_CTIO7:
237 isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local);
238 isp_handle_ctio7(isp, (ct7_entry_t *) local);
239 break;
240
241 case RQSTYPE_ENABLE_LUN:
242 case RQSTYPE_MODIFY_LUN:
243 isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
245 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
244 isp_async(isp, ISPASYNC_TARGET_ACTION, local);
246 break;
247
248 case RQSTYPE_NOTIFY:
245 break;
246
247 case RQSTYPE_NOTIFY:
249 /*
250 * Either the ISP received a SCSI message it can't
251 * handle, or it's returning an Immed. Notify entry
252 * we sent. We can send Immed. Notify entries to
253 * increment the firmware's resource count for them
254 * (we set this initially in the Enable Lun entry).
255 */
256 bus = 0;
257 if (IS_24XX(isp)) {
248 bus = 0;
249 if (IS_24XX(isp)) {
258 isp_get_notify_24xx(isp, inot_24xx,
259 (in_fcentry_24xx_t *)local);
250 isp_get_notify_24xx(isp, inot_24xx, (in_fcentry_24xx_t *)local);
260 inot_24xx = (in_fcentry_24xx_t *) local;
251 inot_24xx = (in_fcentry_24xx_t *) local;
261 status = inot_24xx->in_status;
262 seqid = inot_24xx->in_rxid;
263 isp_prt(isp, ISP_LOGTDEBUG0,
264 "Immediate Notify status=0x%x seqid=0x%x",
265 status, seqid);
266 switch (status) {
267 case IN24XX_LIP_RESET:
268 case IN24XX_LINK_RESET:
269 case IN24XX_PORT_LOGOUT:
270 case IN24XX_PORT_CHANGED:
271 case IN24XX_LINK_FAILED:
272 case IN24XX_SRR_RCVD:
273 case IN24XX_ELS_RCVD:
274 (void) isp_async(isp, ISPASYNC_TARGET_ACTION,
275 &local);
276 break;
277 default:
278 isp_prt(isp, ISP_LOGINFO,
279 "isp_target_notify: unknown status (0x%x)",
280 status);
281 isp_notify_ack(isp, local);
282 break;
283 }
252 isp_handle_24xx_inotify(isp, inot_24xx);
284 break;
253 break;
285 } else if (IS_FC(isp)) {
286 if (FCPARAM(isp)->isp_2klogin) {
287 isp_get_notify_fc_e(isp, inote_fcp,
288 (in_fcentry_e_t *)local);
254 }
255 if (IS_FC(isp)) {
256 if (ISP_CAP_2KLOGIN(isp)) {
257 in_fcentry_e_t *ecp = (in_fcentry_e_t *)local;
258 isp_get_notify_fc_e(isp, inote_fcp, ecp);
259 iid = ecp->in_iid;
260 status = ecp->in_status;
261 seqid = ecp->in_seqid;
289 } else {
262 } else {
290 isp_get_notify_fc(isp, inot_fcp,
291 (in_fcentry_t *)local);
263 in_fcentry_t *fcp = (in_fcentry_t *)local;
264 isp_get_notify_fc(isp, inot_fcp, fcp);
265 iid = fcp->in_iid;
266 status = fcp->in_status;
267 seqid = fcp->in_seqid;
292 }
268 }
293 inot_fcp = (in_fcentry_t *) local;
294 status = inot_fcp->in_status;
295 seqid = inot_fcp->in_seqid;
296 } else {
269 } else {
297 isp_get_notify(isp, inotp, (in_entry_t *)local);
298 inotp = (in_entry_t *) local;
299 status = inotp->in_status & 0xff;
300 seqid = inotp->in_seqid;
270 in_entry_t *inp = (in_entry_t *)local;
271 isp_get_notify(isp, inotp, inp);
272 status = inp->in_status & 0xff;
273 seqid = inp->in_seqid;
274 iid = inp->in_iid;
301 if (IS_DUALBUS(isp)) {
275 if (IS_DUALBUS(isp)) {
302 bus = GET_BUS_VAL(inotp->in_iid);
303 SET_BUS_VAL(inotp->in_iid, 0);
276 bus = GET_BUS_VAL(inp->in_iid);
277 SET_BUS_VAL(inp->in_iid, 0);
304 }
305 }
306
278 }
279 }
280
307 isp_prt(isp, ISP_LOGTDEBUG0,
308 "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
309 bus, status, seqid);
281 isp_prt(isp, ISP_LOGTDEBUG0, "Immediate Notify On Bus %d, status=0x%x seqid=0x%x", bus, status, seqid);
310
311 switch (status) {
312 case IN_MSG_RECEIVED:
313 case IN_IDE_RECEIVED:
314 if (IS_FC(isp)) {
315 isp_got_msg_fc(isp, (in_fcentry_t *)local);
316 } else {
317 isp_got_msg(isp, (in_entry_t *)local);
318 }
319 break;
320 case IN_RSRC_UNAVAIL:
321 isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
282
283 switch (status) {
284 case IN_MSG_RECEIVED:
285 case IN_IDE_RECEIVED:
286 if (IS_FC(isp)) {
287 isp_got_msg_fc(isp, (in_fcentry_t *)local);
288 } else {
289 isp_got_msg(isp, (in_entry_t *)local);
290 }
291 break;
292 case IN_RSRC_UNAVAIL:
293 isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
322 isp_notify_ack(isp, local);
294 (void) isp_notify_ack(isp, local);
323 break;
295 break;
324 case IN_RESET:
325 {
326 /*
327 * We form the notify structure here because we need
328 * to mark it as needing a NOTIFY ACK on return.
329 */
330 tmd_notify_t notify;
331
296
332 MEMZERO(&notify, sizeof (tmd_notify_t));
297 case IN_RESET:
298 ISP_MEMZERO(&notify, sizeof (isp_notify_t));
333 notify.nt_hba = isp;
299 notify.nt_hba = isp;
334 notify.nt_iid = INI_ANY;
335 /* nt_tgt set in outer layers */
300 notify.nt_wwn = INI_ANY;
301 notify.nt_tgt = TGT_ANY;
302 notify.nt_nphdl = iid;
303 notify.nt_sid = PORT_ANY;
304 notify.nt_did = PORT_ANY;
336 notify.nt_lun = LUN_ANY;
337 notify.nt_tagval = TAG_ANY;
305 notify.nt_lun = LUN_ANY;
306 notify.nt_tagval = TAG_ANY;
307 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
338 notify.nt_ncode = NT_BUS_RESET;
339 notify.nt_need_ack = 1;
308 notify.nt_ncode = NT_BUS_RESET;
309 notify.nt_need_ack = 1;
340 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
310 notify.nt_lreserved = local;
311 isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
341 break;
312 break;
342 }
313
343 case IN_PORT_LOGOUT:
314 case IN_PORT_LOGOUT:
315 ISP_MEMZERO(&notify, sizeof (isp_notify_t));
316 notify.nt_hba = isp;
317 notify.nt_wwn = INI_ANY;
318 notify.nt_nphdl = iid;
319 notify.nt_sid = PORT_ANY;
320 notify.nt_did = PORT_ANY;
321 notify.nt_ncode = NT_LOGOUT;
322 notify.nt_need_ack = 1;
323 notify.nt_lreserved = local;
324 isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
325 break;
326
344 case IN_ABORT_TASK:
327 case IN_ABORT_TASK:
345 case IN_PORT_CHANGED:
328 ISP_MEMZERO(&notify, sizeof (isp_notify_t));
329 notify.nt_hba = isp;
330 notify.nt_wwn = INI_ANY;
331 notify.nt_nphdl = iid;
332 notify.nt_sid = PORT_ANY;
333 notify.nt_did = PORT_ANY;
334 notify.nt_ncode = NT_ABORT_TASK;
335 notify.nt_need_ack = 1;
336 notify.nt_lreserved = local;
337 isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
338 break;
339
346 case IN_GLOBAL_LOGO:
340 case IN_GLOBAL_LOGO:
347 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
341 isp_prt(isp, ISP_LOGTINFO, "%s: all ports logged out", __func__);
342 ISP_MEMZERO(&notify, sizeof (isp_notify_t));
343 notify.nt_hba = isp;
344 notify.nt_wwn = INI_ANY;
345 notify.nt_nphdl = NIL_HANDLE;
346 notify.nt_sid = PORT_ANY;
347 notify.nt_did = PORT_ANY;
348 notify.nt_ncode = NT_GLOBAL_LOGOUT;
349 isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
350 (void) isp_notify_ack(isp, local);
348 break;
351 break;
352
353 case IN_PORT_CHANGED:
354 isp_prt(isp, ISP_LOGTINFO, "%s: port changed", __func__);
355 (void) isp_notify_ack(isp, local);
356 break;
357
349 default:
358 default:
350 isp_prt(isp, ISP_LOGINFO,
351 "isp_target_notify: unknown status (0x%x)",
352 status);
353 isp_notify_ack(isp, local);
359 ISP_SNPRINTF(local, sizeof local, "%s: unknown status to RQSTYPE_NOTIFY (0x%x)", __func__, status);
360 isp_print_bytes(isp, local, QENTRY_LEN, vptr);
361 (void) isp_notify_ack(isp, local);
354 break;
355 }
356 break;
357
358 case RQSTYPE_NOTIFY_ACK:
359 /*
360 * The ISP is acknowledging our acknowledgement of an
361 * Immediate Notify entry for some asynchronous event.
362 */
363 if (IS_24XX(isp)) {
362 break;
363 }
364 break;
365
366 case RQSTYPE_NOTIFY_ACK:
367 /*
368 * The ISP is acknowledging our acknowledgement of an
369 * Immediate Notify entry for some asynchronous event.
370 */
371 if (IS_24XX(isp)) {
364 isp_get_notify_ack_24xx(isp, nack_24xx,
365 (na_fcentry_24xx_t *) local);
372 isp_get_notify_ack_24xx(isp, nack_24xx, (na_fcentry_24xx_t *) local);
366 nack_24xx = (na_fcentry_24xx_t *) local;
367 if (nack_24xx->na_status != NA_OK) {
368 level = ISP_LOGINFO;
369 } else {
370 level = ISP_LOGTDEBUG1;
371 }
373 nack_24xx = (na_fcentry_24xx_t *) local;
374 if (nack_24xx->na_status != NA_OK) {
375 level = ISP_LOGINFO;
376 } else {
377 level = ISP_LOGTDEBUG1;
378 }
372 isp_prt(isp, level,
373 "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x",
374 nack_24xx->na_status, nack_24xx->na_status_subcode,
375 nack_24xx->na_rxid);
379 isp_prt(isp, level, "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x", nack_24xx->na_status, nack_24xx->na_status_subcode, nack_24xx->na_rxid);
376 } else if (IS_FC(isp)) {
380 } else if (IS_FC(isp)) {
377 if (FCPARAM(isp)->isp_2klogin) {
378 isp_get_notify_ack_fc_e(isp, nacke_fcp,
379 (na_fcentry_e_t *)local);
381 if (ISP_CAP_2KLOGIN(isp)) {
382 isp_get_notify_ack_fc_e(isp, nacke_fcp, (na_fcentry_e_t *)local);
380 } else {
383 } else {
381 isp_get_notify_ack_fc(isp, nack_fcp,
382 (na_fcentry_t *)local);
384 isp_get_notify_ack_fc(isp, nack_fcp, (na_fcentry_t *)local);
383 }
384 nack_fcp = (na_fcentry_t *)local;
385 if (nack_fcp->na_status != NA_OK) {
386 level = ISP_LOGINFO;
387 } else {
388 level = ISP_LOGTDEBUG1;
389 }
385 }
386 nack_fcp = (na_fcentry_t *)local;
387 if (nack_fcp->na_status != NA_OK) {
388 level = ISP_LOGINFO;
389 } else {
390 level = ISP_LOGTDEBUG1;
391 }
390 isp_prt(isp, level,
391 "Notify Ack Status=0x%x seqid 0x%x",
392 nack_fcp->na_status, nack_fcp->na_seqid);
392 isp_prt(isp, level, "Notify Ack Status=0x%x seqid 0x%x", nack_fcp->na_status, nack_fcp->na_seqid);
393 } else {
394 isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
395 nackp = (na_entry_t *)local;
396 if (nackp->na_status != NA_OK) {
397 level = ISP_LOGINFO;
398 } else {
399 level = ISP_LOGTDEBUG1;
400 }
393 } else {
394 isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
395 nackp = (na_entry_t *)local;
396 if (nackp->na_status != NA_OK) {
397 level = ISP_LOGINFO;
398 } else {
399 level = ISP_LOGTDEBUG1;
400 }
401 isp_prt(isp, level,
402 "Notify Ack event 0x%x status=0x%x seqid 0x%x",
403 nackp->na_event, nackp->na_status, nackp->na_seqid);
401 isp_prt(isp, level, "Notify Ack event 0x%x status=0x%x seqid 0x%x", nackp->na_event, nackp->na_status, nackp->na_seqid);
404 }
405 break;
406
407 case RQSTYPE_ABTS_RCVD:
408 isp_get_abts(isp, abts, (abts_t *)local);
402 }
403 break;
404
405 case RQSTYPE_ABTS_RCVD:
406 isp_get_abts(isp, abts, (abts_t *)local);
409 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
407 isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
410 break;
411 case RQSTYPE_ABTS_RSP:
412 isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local);
413 abts_rsp = (abts_rsp_t *) local;
414 if (abts_rsp->abts_rsp_status) {
415 level = ISP_LOGINFO;
416 } else {
417 level = ISP_LOGTDEBUG0;
418 }
408 break;
409 case RQSTYPE_ABTS_RSP:
410 isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local);
411 abts_rsp = (abts_rsp_t *) local;
412 if (abts_rsp->abts_rsp_status) {
413 level = ISP_LOGINFO;
414 } else {
415 level = ISP_LOGTDEBUG0;
416 }
419 isp_prt(isp, level,
420 "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)",
421 abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status,
422 abts_rsp->abts_rsp_payload.rsp.subcode1,
423 abts_rsp->abts_rsp_payload.rsp.subcode2);
417 isp_prt(isp, level, "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)", abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status,
418 abts_rsp->abts_rsp_payload.rsp.subcode1, abts_rsp->abts_rsp_payload.rsp.subcode2);
424 break;
425 default:
419 break;
420 default:
426 isp_prt(isp, ISP_LOGERR,
427 "Unknown entry type 0x%x in isp_target_notify", type);
421 isp_prt(isp, ISP_LOGERR, "%s: unknown entry type 0x%x", __func__, type);
428 rval = 0;
429 break;
430 }
431#undef atiop
432#undef at2iop
433#undef at2eiop
434#undef at7iop
435#undef ctiop

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

447#undef hack_24xx
448#undef abts
449#undef abts_rsp
450#undef els
451#undef hdrp
452 return (rval);
453}
454
422 rval = 0;
423 break;
424 }
425#undef atiop
426#undef at2iop
427#undef at2eiop
428#undef at7iop
429#undef ctiop

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

441#undef hack_24xx
442#undef abts
443#undef abts_rsp
444#undef els
445#undef hdrp
446 return (rval);
447}
448
455
449
456/*
450/*
457 * Toggle (on/off) target mode for bus/target/lun
451 * Toggle (on/off) target mode for bus/target/lun.
458 *
459 * The caller has checked for overlap and legality.
460 *
461 * Note that not all of bus, target or lun can be paid attention to.
462 * Note also that this action will not be complete until the f/w writes
452 *
453 * The caller has checked for overlap and legality.
454 *
455 * Note that not all of bus, target or lun can be paid attention to.
456 * Note also that this action will not be complete until the f/w writes
463 * response entry. The caller is responsible for synchronizing this.
457 * a response entry. The caller is responsible for synchronizing with this.
464 */
465int
458 */
459int
466isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
467 int cmd_cnt, int inot_cnt, uint32_t opaque)
460isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int lun, int cmd_cnt, int inot_cnt)
468{
469 lun_entry_t el;
461{
462 lun_entry_t el;
470 uint32_t nxti, optr;
471 void *outp;
472
463 void *outp;
464
473
474 MEMZERO(&el, sizeof (el));
465 ISP_MEMZERO(&el, sizeof (el));
475 if (IS_DUALBUS(isp)) {
476 el.le_rsvd = (bus & 0x1) << 7;
477 }
478 el.le_cmd_count = cmd_cnt;
479 el.le_in_count = inot_cnt;
480 if (cmd == RQSTYPE_ENABLE_LUN) {
481 if (IS_SCSI(isp)) {
482 el.le_flags = LUN_TQAE|LUN_DISAD;

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

490 } else if (cmd == -RQSTYPE_MODIFY_LUN) {
491 cmd = RQSTYPE_MODIFY_LUN;
492 el.le_ops = LUN_CCDECR | LUN_INDECR;
493 } else {
494 el.le_ops = LUN_CCINCR | LUN_ININCR;
495 }
496 el.le_header.rqs_entry_type = cmd;
497 el.le_header.rqs_entry_count = 1;
466 if (IS_DUALBUS(isp)) {
467 el.le_rsvd = (bus & 0x1) << 7;
468 }
469 el.le_cmd_count = cmd_cnt;
470 el.le_in_count = inot_cnt;
471 if (cmd == RQSTYPE_ENABLE_LUN) {
472 if (IS_SCSI(isp)) {
473 el.le_flags = LUN_TQAE|LUN_DISAD;

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

481 } else if (cmd == -RQSTYPE_MODIFY_LUN) {
482 cmd = RQSTYPE_MODIFY_LUN;
483 el.le_ops = LUN_CCDECR | LUN_INDECR;
484 } else {
485 el.le_ops = LUN_CCINCR | LUN_ININCR;
486 }
487 el.le_header.rqs_entry_type = cmd;
488 el.le_header.rqs_entry_count = 1;
498 el.le_reserved = opaque;
499 if (IS_SCSI(isp)) {
489 if (IS_SCSI(isp)) {
500 el.le_tgt = tgt;
490 el.le_tgt = SDPARAM(isp, bus)->isp_initiator_id;
501 el.le_lun = lun;
491 el.le_lun = lun;
502 } else if (FCPARAM(isp)->isp_sccfw == 0) {
492 } else if (ISP_CAP_SCCFW(isp) == 0) {
503 el.le_lun = lun;
504 }
505 el.le_timeout = 30;
506
493 el.le_lun = lun;
494 }
495 el.le_timeout = 30;
496
507 if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
508 isp_prt(isp, ISP_LOGERR,
509 "Request Queue Overflow in isp_lun_cmd");
497 outp = isp_getrqentry(isp);
498 if (outp == NULL) {
499 isp_prt(isp, ISP_LOGERR, rqo, __func__);
510 return (-1);
511 }
500 return (-1);
501 }
512 ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
513 isp_put_enable_lun(isp, &el, outp);
502 isp_put_enable_lun(isp, &el, outp);
514 ISP_ADD_REQUEST(isp, nxti);
503 ISP_TDQE(isp, "isp_lun_cmd", isp->isp_reqidx, &el);
504 ISP_SYNC_REQUEST(isp);
515 return (0);
516}
517
505 return (0);
506}
507
518
519int
520isp_target_put_entry(ispsoftc_t *isp, void *ap)
521{
522 void *outp;
508int
509isp_target_put_entry(ispsoftc_t *isp, void *ap)
510{
511 void *outp;
523 uint32_t nxti, optr;
524 uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
525
512 uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
513
526 if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
527 isp_prt(isp, ISP_LOGWARN,
528 "Request Queue Overflow in isp_target_put_entry");
514 outp = isp_getrqentry(isp);
515 if (outp == NULL) {
516 isp_prt(isp, ISP_LOGWARN, rqo, __func__);
529 return (-1);
530 }
531 switch (etype) {
532 case RQSTYPE_ATIO:
533 isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
534 break;
535 case RQSTYPE_ATIO2:
517 return (-1);
518 }
519 switch (etype) {
520 case RQSTYPE_ATIO:
521 isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
522 break;
523 case RQSTYPE_ATIO2:
536 if (FCPARAM(isp)->isp_2klogin) {
537 isp_put_atio2e(isp, (at2e_entry_t *) ap,
538 (at2e_entry_t *) outp);
524 if (ISP_CAP_2KLOGIN(isp)) {
525 isp_put_atio2e(isp, (at2e_entry_t *) ap, (at2e_entry_t *) outp);
539 } else {
526 } else {
540 isp_put_atio2(isp, (at2_entry_t *) ap,
541 (at2_entry_t *) outp);
527 isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
542 }
543 break;
544 case RQSTYPE_CTIO:
545 isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
546 break;
547 case RQSTYPE_CTIO2:
528 }
529 break;
530 case RQSTYPE_CTIO:
531 isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
532 break;
533 case RQSTYPE_CTIO2:
548 if (FCPARAM(isp)->isp_2klogin) {
549 isp_put_ctio2e(isp, (ct2e_entry_t *) ap,
550 (ct2e_entry_t *) outp);
534 if (ISP_CAP_2KLOGIN(isp)) {
535 isp_put_ctio2e(isp, (ct2e_entry_t *) ap, (ct2e_entry_t *) outp);
551 } else {
536 } else {
552 isp_put_ctio2(isp, (ct2_entry_t *) ap,
553 (ct2_entry_t *) outp);
537 isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
554 }
555 break;
556 case RQSTYPE_CTIO7:
557 isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp);
558 break;
559 default:
538 }
539 break;
540 case RQSTYPE_CTIO7:
541 isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp);
542 break;
543 default:
560 isp_prt(isp, ISP_LOGERR,
561 "Unknown type 0x%x in isp_put_entry", etype);
544 isp_prt(isp, ISP_LOGERR, "%s: Unknown type 0x%x", __func__, etype);
562 return (-1);
563 }
545 return (-1);
546 }
564 ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
565 ISP_ADD_REQUEST(isp, nxti);
547 ISP_TDQE(isp, __func__, isp->isp_reqidx, ap);
548 ISP_SYNC_REQUEST(isp);
566 return (0);
567}
568
569int
570isp_target_put_atio(ispsoftc_t *isp, void *arg)
571{
572 union {
573 at_entry_t _atio;
574 at2_entry_t _atio2;
575 at2e_entry_t _atio2e;
576 } atun;
577
549 return (0);
550}
551
552int
553isp_target_put_atio(ispsoftc_t *isp, void *arg)
554{
555 union {
556 at_entry_t _atio;
557 at2_entry_t _atio2;
558 at2e_entry_t _atio2e;
559 } atun;
560
578 MEMZERO(&atun, sizeof atun);
561 ISP_MEMZERO(&atun, sizeof atun);
579 if (IS_FC(isp)) {
580 at2_entry_t *aep = arg;
581 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
582 atun._atio2.at_header.rqs_entry_count = 1;
562 if (IS_FC(isp)) {
563 at2_entry_t *aep = arg;
564 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
565 atun._atio2.at_header.rqs_entry_count = 1;
583 if (FCPARAM(isp)->isp_sccfw) {
566 if (ISP_CAP_SCCFW(isp)) {
584 atun._atio2.at_scclun = aep->at_scclun;
585 } else {
586 atun._atio2.at_lun = (uint8_t) aep->at_lun;
587 }
567 atun._atio2.at_scclun = aep->at_scclun;
568 } else {
569 atun._atio2.at_lun = (uint8_t) aep->at_lun;
570 }
588 if (FCPARAM(isp)->isp_2klogin) {
571 if (ISP_CAP_2KLOGIN(isp)) {
589 atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
590 } else {
591 atun._atio2.at_iid = aep->at_iid;
592 }
593 atun._atio2.at_rxid = aep->at_rxid;
594 atun._atio2.at_status = CT_OK;
595 } else {
596 at_entry_t *aep = arg;

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

622 * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
623 *
624 * For both parallel && fibre channel, we use the feature that does
625 * an automatic resource autoreplenish so we don't have then later do
626 * put of an atio to replenish the f/w's resource count.
627 */
628
629int
572 atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
573 } else {
574 atun._atio2.at_iid = aep->at_iid;
575 }
576 atun._atio2.at_rxid = aep->at_rxid;
577 atun._atio2.at_status = CT_OK;
578 } else {
579 at_entry_t *aep = arg;

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

605 * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
606 *
607 * For both parallel && fibre channel, we use the feature that does
608 * an automatic resource autoreplenish so we don't have then later do
609 * put of an atio to replenish the f/w's resource count.
610 */
611
612int
630isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
613isp_endcmd(ispsoftc_t *isp, ...)
631{
614{
632 int sts;
615 uint32_t code, hdl;
616 uint8_t sts;
633 union {
634 ct_entry_t _ctio;
635 ct2_entry_t _ctio2;
636 ct2e_entry_t _ctio2e;
637 ct7_entry_t _ctio7;
638 } un;
617 union {
618 ct_entry_t _ctio;
619 ct2_entry_t _ctio2;
620 ct2e_entry_t _ctio2e;
621 ct7_entry_t _ctio7;
622 } un;
623 va_list ap;
639
624
640 MEMZERO(&un, sizeof un);
641 sts = code & 0xff;
625 ISP_MEMZERO(&un, sizeof un);
642
643 if (IS_24XX(isp)) {
626
627 if (IS_24XX(isp)) {
644 at7_entry_t *aep = arg;
628 int vpidx, nphdl;
629 at7_entry_t *aep;
645 ct7_entry_t *cto = &un._ctio7;
646
630 ct7_entry_t *cto = &un._ctio7;
631
632 va_start(ap, isp);
633 aep = va_arg(ap, at7_entry_t *);
634 nphdl = va_arg(ap, int);
635 /*
636 * Note that vpidx may equal 0xff (unknown) here
637 */
638 vpidx = va_arg(ap, int);
639 code = va_arg(ap, uint32_t);
640 hdl = va_arg(ap, uint32_t);
641 va_end(ap);
642 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] chan %d code %x", __func__, aep->at_rxid, vpidx, code);
643
644 sts = code & 0xff;
647 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
648 cto->ct_header.rqs_entry_count = 1;
645 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
646 cto->ct_header.rqs_entry_count = 1;
649/* XXXX */ cto->ct_nphdl = aep->at_hdr.seq_id;
647 cto->ct_nphdl = nphdl;
650 cto->ct_rxid = aep->at_rxid;
648 cto->ct_rxid = aep->at_rxid;
651 cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) |
652 aep->at_hdr.s_id[2];
649 cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
653 cto->ct_iid_hi = aep->at_hdr.s_id[0];
654 cto->ct_oxid = aep->at_hdr.ox_id;
655 cto->ct_scsi_status = sts;
650 cto->ct_iid_hi = aep->at_hdr.s_id[0];
651 cto->ct_oxid = aep->at_hdr.ox_id;
652 cto->ct_scsi_status = sts;
656 cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS;
657 if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
658 cto->rsp.m1.ct_resplen = 16;
653 cto->ct_vpidx = vpidx;
654 cto->ct_flags = CT7_NOACK;
655 if (code & ECMD_TERMINATE) {
656 cto->ct_flags |= CT7_TERMINATE;
657 } else if (code & ECMD_SVALID) {
658 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS;
659 cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8);
660 cto->rsp.m1.ct_resplen = cto->ct_senselen = min(16, MAXRESPLEN_24XX);
661 ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp));
659 cto->rsp.m1.ct_resp[0] = 0xf0;
660 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
661 cto->rsp.m1.ct_resp[7] = 8;
662 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
663 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
662 cto->rsp.m1.ct_resp[0] = 0xf0;
663 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
664 cto->rsp.m1.ct_resp[7] = 8;
665 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
666 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
667 } else {
668 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS;
664 }
665 if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) {
666 cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
669 }
670 if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) {
671 cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
667 cto->ct_scsi_status |= CT2_DATA_UNDER;
672 if (cto->ct_resid < 0) {
673 cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8);
674 } else if (cto->ct_resid > 0) {
675 cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8);
676 }
668 }
669 cto->ct_syshandle = hdl;
670 } else if (IS_FC(isp)) {
677 }
678 cto->ct_syshandle = hdl;
679 } else if (IS_FC(isp)) {
671 at2_entry_t *aep = arg;
680 at2_entry_t *aep;
672 ct2_entry_t *cto = &un._ctio2;
673
681 ct2_entry_t *cto = &un._ctio2;
682
683 va_start(ap, isp);
684 aep = va_arg(ap, at2_entry_t *);
685 code = va_arg(ap, uint32_t);
686 hdl = va_arg(ap, uint32_t);
687 va_end(ap);
688
689 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] code %x", __func__, aep->at_rxid, code);
690
691 sts = code & 0xff;
674 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
675 cto->ct_header.rqs_entry_count = 1;
692 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
693 cto->ct_header.rqs_entry_count = 1;
676 if (FCPARAM(isp)->isp_sccfw == 0) {
694 if (ISP_CAP_SCCFW(isp) == 0) {
677 cto->ct_lun = aep->at_lun;
678 }
695 cto->ct_lun = aep->at_lun;
696 }
679 if (FCPARAM(isp)->isp_2klogin) {
697 if (ISP_CAP_2KLOGIN(isp)) {
680 un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
681 } else {
682 cto->ct_iid = aep->at_iid;
683 }
684 cto->ct_rxid = aep->at_rxid;
685 cto->rsp.m1.ct_scsi_status = sts;
686 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
687 if (hdl == 0) {

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

697 cto->rsp.m1.ct_resp[7] = 8;
698 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
699 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
700 cto->rsp.m1.ct_senselen = 16;
701 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
702 }
703 cto->ct_syshandle = hdl;
704 } else {
698 un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
699 } else {
700 cto->ct_iid = aep->at_iid;
701 }
702 cto->ct_rxid = aep->at_rxid;
703 cto->rsp.m1.ct_scsi_status = sts;
704 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
705 if (hdl == 0) {

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

715 cto->rsp.m1.ct_resp[7] = 8;
716 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
717 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
718 cto->rsp.m1.ct_senselen = 16;
719 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
720 }
721 cto->ct_syshandle = hdl;
722 } else {
705 at_entry_t *aep = arg;
723 at_entry_t *aep;
706 ct_entry_t *cto = &un._ctio;
707
724 ct_entry_t *cto = &un._ctio;
725
726 va_start(ap, isp);
727 aep = va_arg(ap, at_entry_t *);
728 code = va_arg(ap, uint32_t);
729 hdl = va_arg(ap, uint32_t);
730 va_end(ap);
731 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [IID %d] code %x", __func__, aep->at_iid, code);
732 sts = code;
733
708 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
709 cto->ct_header.rqs_entry_count = 1;
710 cto->ct_fwhandle = aep->at_handle;
711 cto->ct_iid = aep->at_iid;
712 cto->ct_tgt = aep->at_tgt;
713 cto->ct_lun = aep->at_lun;
714 cto->ct_tag_type = aep->at_tag_type;
715 cto->ct_tag_val = aep->at_tag_val;

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

724 cto->ct_syshandle = hdl;
725 }
726 return (isp_target_put_entry(isp, &un));
727}
728
729/*
730 * These are either broadcast events or specifically CTIO fast completion
731 */
734 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
735 cto->ct_header.rqs_entry_count = 1;
736 cto->ct_fwhandle = aep->at_handle;
737 cto->ct_iid = aep->at_iid;
738 cto->ct_tgt = aep->at_tgt;
739 cto->ct_lun = aep->at_lun;
740 cto->ct_tag_type = aep->at_tag_type;
741 cto->ct_tag_val = aep->at_tag_val;

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

750 cto->ct_syshandle = hdl;
751 }
752 return (isp_target_put_entry(isp, &un));
753}
754
755/*
756 * These are either broadcast events or specifically CTIO fast completion
757 */
758
732int
733isp_target_async(ispsoftc_t *isp, int bus, int event)
734{
759int
760isp_target_async(ispsoftc_t *isp, int bus, int event)
761{
735 tmd_notify_t notify;
762 isp_notify_t notify;
736
763
737 MEMZERO(&notify, sizeof (tmd_notify_t));
764 ISP_MEMZERO(&notify, sizeof (isp_notify_t));
738 notify.nt_hba = isp;
765 notify.nt_hba = isp;
739 notify.nt_iid = INI_ANY;
740 /* nt_tgt set in outer layers */
766 notify.nt_wwn = INI_ANY;
767 notify.nt_nphdl = NIL_HANDLE;
768 notify.nt_sid = PORT_ANY;
769 notify.nt_did = PORT_ANY;
770 notify.nt_tgt = TGT_ANY;
771 notify.nt_channel = bus;
741 notify.nt_lun = LUN_ANY;
742 notify.nt_tagval = TAG_ANY;
772 notify.nt_lun = LUN_ANY;
773 notify.nt_tagval = TAG_ANY;
774 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
743
775
744 if (IS_SCSI(isp)) {
745 TAG_INSERT_BUS(notify.nt_tagval, bus);
746 }
747
748 switch (event) {
749 case ASYNC_LOOP_UP:
750 case ASYNC_PTPMODE:
776 switch (event) {
777 case ASYNC_LOOP_UP:
778 case ASYNC_PTPMODE:
779 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP UP", __func__);
751 notify.nt_ncode = NT_LINK_UP;
780 notify.nt_ncode = NT_LINK_UP;
752 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
781 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
753 break;
754 case ASYNC_LOOP_DOWN:
782 break;
783 case ASYNC_LOOP_DOWN:
784 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP DOWN", __func__);
755 notify.nt_ncode = NT_LINK_DOWN;
785 notify.nt_ncode = NT_LINK_DOWN;
756 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
786 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
757 break;
758 case ASYNC_LIP_ERROR:
759 case ASYNC_LIP_F8:
760 case ASYNC_LIP_OCCURRED:
761 case ASYNC_LOOP_RESET:
787 break;
788 case ASYNC_LIP_ERROR:
789 case ASYNC_LIP_F8:
790 case ASYNC_LIP_OCCURRED:
791 case ASYNC_LOOP_RESET:
792 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LIP RESET", __func__);
762 notify.nt_ncode = NT_LIP_RESET;
793 notify.nt_ncode = NT_LIP_RESET;
763 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
794 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
764 break;
765 case ASYNC_BUS_RESET:
766 case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */
795 break;
796 case ASYNC_BUS_RESET:
797 case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */
798 isp_prt(isp, ISP_LOGTDEBUG0, "%s: BUS RESET", __func__);
767 notify.nt_ncode = NT_BUS_RESET;
799 notify.nt_ncode = NT_BUS_RESET;
768 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
800 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
769 break;
770 case ASYNC_DEVICE_RESET:
801 break;
802 case ASYNC_DEVICE_RESET:
803 isp_prt(isp, ISP_LOGTDEBUG0, "%s: DEVICE RESET", __func__);
771 notify.nt_ncode = NT_TARGET_RESET;
804 notify.nt_ncode = NT_TARGET_RESET;
772 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
805 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
773 break;
774 case ASYNC_CTIO_DONE:
775 {
776 uint8_t storage[QENTRY_LEN];
806 break;
807 case ASYNC_CTIO_DONE:
808 {
809 uint8_t storage[QENTRY_LEN];
810 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO DONE", __func__);
777 memset(storage, 0, QENTRY_LEN);
778 if (IS_24XX(isp)) {
779 ct7_entry_t *ct = (ct7_entry_t *) storage;
780 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
781 ct->ct_nphdl = CT7_OK;
782 ct->ct_syshandle = bus;
811 memset(storage, 0, QENTRY_LEN);
812 if (IS_24XX(isp)) {
813 ct7_entry_t *ct = (ct7_entry_t *) storage;
814 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
815 ct->ct_nphdl = CT7_OK;
816 ct->ct_syshandle = bus;
783 ct->ct_flags = CT7_SENDSTATUS|CT7_FASTPOST;
817 ct->ct_flags = CT7_SENDSTATUS;
784 } else if (IS_FC(isp)) {
785 /* This should also suffice for 2K login code */
786 ct2_entry_t *ct = (ct2_entry_t *) storage;
787 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
788 ct->ct_status = CT_OK;
789 ct->ct_syshandle = bus;
790 ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST;
791 } else {
792 ct_entry_t *ct = (ct_entry_t *) storage;
793 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO;
794 ct->ct_status = CT_OK;
795 ct->ct_fwhandle = bus;
796 ct->ct_flags = CT_SENDSTATUS;
797 }
818 } else if (IS_FC(isp)) {
819 /* This should also suffice for 2K login code */
820 ct2_entry_t *ct = (ct2_entry_t *) storage;
821 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
822 ct->ct_status = CT_OK;
823 ct->ct_syshandle = bus;
824 ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST;
825 } else {
826 ct_entry_t *ct = (ct_entry_t *) storage;
827 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO;
828 ct->ct_status = CT_OK;
829 ct->ct_fwhandle = bus;
830 ct->ct_flags = CT_SENDSTATUS;
831 }
798 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
832 isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
799 break;
800 }
801 default:
833 break;
834 }
835 default:
802 isp_prt(isp, ISP_LOGERR,
803 "isp_target_async: unknown event 0x%x", event);
836 isp_prt(isp, ISP_LOGERR, "%s: unknown event 0x%x", __func__, event);
804 if (isp->isp_state == ISP_RUNSTATE) {
837 if (isp->isp_state == ISP_RUNSTATE) {
805 isp_notify_ack(isp, NULL);
838 (void) isp_notify_ack(isp, NULL);
806 }
807 break;
808 }
809 return (0);
810}
811
812
813/*
814 * Process a received message.
815 * The ISP firmware can handle most messages, there are only
816 * a few that we need to deal with:
817 * - abort: clean up the current command
818 * - abort tag and clear queue
819 */
820
821static void
822isp_got_msg(ispsoftc_t *isp, in_entry_t *inp)
823{
839 }
840 break;
841 }
842 return (0);
843}
844
845
846/*
847 * Process a received message.
848 * The ISP firmware can handle most messages, there are only
849 * a few that we need to deal with:
850 * - abort: clean up the current command
851 * - abort tag and clear queue
852 */
853
854static void
855isp_got_msg(ispsoftc_t *isp, in_entry_t *inp)
856{
824 tmd_notify_t nt;
857 isp_notify_t notify;
825 uint8_t status = inp->in_status & ~QLTM_SVALID;
826
858 uint8_t status = inp->in_status & ~QLTM_SVALID;
859
827 MEMZERO(&nt, sizeof (nt));
828 nt.nt_hba = isp;
829 nt.nt_iid = GET_IID_VAL(inp->in_iid);
830 nt.nt_tgt = inp->in_tgt;
831 nt.nt_lun = inp->in_lun;
832 IN_MAKE_TAGID(nt.nt_tagval, GET_BUS_VAL(inp->in_iid), 0, inp);
833 nt.nt_lreserved = inp;
860 ISP_MEMZERO(&notify, sizeof (notify));
861 notify.nt_hba = isp;
862 notify.nt_wwn = INI_ANY;
863 notify.nt_nphdl = GET_IID_VAL(inp->in_iid);
864 notify.nt_sid = PORT_ANY;
865 notify.nt_did = PORT_ANY;
866 notify.nt_channel = GET_BUS_VAL(inp->in_iid);
867 notify.nt_tgt = inp->in_tgt;
868 notify.nt_lun = inp->in_lun;
869 IN_MAKE_TAGID(notify.nt_tagval, inp);
870 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
871 notify.nt_lreserved = inp;
834
835 if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
836 switch (inp->in_msg[0]) {
837 case MSG_ABORT:
872
873 if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
874 switch (inp->in_msg[0]) {
875 case MSG_ABORT:
838 nt.nt_ncode = NT_ABORT_TASK_SET;
876 notify.nt_ncode = NT_ABORT_TASK_SET;
839 break;
840 case MSG_BUS_DEV_RESET:
877 break;
878 case MSG_BUS_DEV_RESET:
841 nt.nt_ncode = NT_TARGET_RESET;
879 notify.nt_ncode = NT_TARGET_RESET;
842 break;
843 case MSG_ABORT_TAG:
880 break;
881 case MSG_ABORT_TAG:
844 nt.nt_ncode = NT_ABORT_TASK;
882 notify.nt_ncode = NT_ABORT_TASK;
845 break;
846 case MSG_CLEAR_QUEUE:
883 break;
884 case MSG_CLEAR_QUEUE:
847 nt.nt_ncode = NT_CLEAR_TASK_SET;
885 notify.nt_ncode = NT_CLEAR_TASK_SET;
848 break;
849 case MSG_REL_RECOVERY:
886 break;
887 case MSG_REL_RECOVERY:
850 nt.nt_ncode = NT_CLEAR_ACA;
888 notify.nt_ncode = NT_CLEAR_ACA;
851 break;
852 case MSG_TERM_IO_PROC:
889 break;
890 case MSG_TERM_IO_PROC:
853 nt.nt_ncode = NT_ABORT_TASK;
891 notify.nt_ncode = NT_ABORT_TASK;
854 break;
855 case MSG_LUN_RESET:
892 break;
893 case MSG_LUN_RESET:
856 nt.nt_ncode = NT_LUN_RESET;
894 notify.nt_ncode = NT_LUN_RESET;
857 break;
858 default:
895 break;
896 default:
859 isp_prt(isp, ISP_LOGERR,
860 "unhandled message 0x%x", inp->in_msg[0]);
861 isp_notify_ack(isp, inp);
897 isp_prt(isp, ISP_LOGERR, "%s: unhandled message 0x%x", __func__, inp->in_msg[0]);
898 (void) isp_notify_ack(isp, inp);
862 return;
863 }
899 return;
900 }
864 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
901 isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
865 } else {
902 } else {
866 isp_prt(isp, ISP_LOGERR,
867 "unknown immediate notify status 0x%x", inp->in_status);
868 isp_notify_ack(isp, inp);
903 isp_prt(isp, ISP_LOGERR, "%s: unknown immediate notify status 0x%x", __func__, inp->in_status);
904 (void) isp_notify_ack(isp, inp);
869 }
870}
871
872/*
873 * Synthesize a message from the task management flags in a FCP_CMND_IU.
874 */
875static void
876isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
877{
905 }
906}
907
908/*
909 * Synthesize a message from the task management flags in a FCP_CMND_IU.
910 */
911static void
912isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
913{
878 tmd_notify_t nt;
914 isp_notify_t notify;
879 static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x";
915 static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x";
880 static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x "
881 "task flags 0x%x seq 0x%x\n";
916 static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x task flags 0x%x seq 0x%x\n";
882 uint16_t seqid, loopid;
883
917 uint16_t seqid, loopid;
918
884 MEMZERO(&nt, sizeof (tmd_notify_t));
885 nt.nt_hba = isp;
886 if (FCPARAM(isp)->isp_2klogin) {
887 nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid;
919 ISP_MEMZERO(&notify, sizeof (isp_notify_t));
920 notify.nt_hba = isp;
921 notify.nt_wwn = INI_ANY;
922 if (ISP_CAP_2KLOGIN(isp)) {
923 notify.nt_nphdl = ((in_fcentry_e_t *)inp)->in_iid;
888 loopid = ((in_fcentry_e_t *)inp)->in_iid;
889 seqid = ((in_fcentry_e_t *)inp)->in_seqid;
890 } else {
924 loopid = ((in_fcentry_e_t *)inp)->in_iid;
925 seqid = ((in_fcentry_e_t *)inp)->in_seqid;
926 } else {
891 nt.nt_iid = inp->in_iid;
927 notify.nt_nphdl = inp->in_iid;
892 loopid = inp->in_iid;
893 seqid = inp->in_seqid;
894 }
928 loopid = inp->in_iid;
929 seqid = inp->in_seqid;
930 }
931 notify.nt_sid = PORT_ANY;
932 notify.nt_did = PORT_ANY;
933
895 /* nt_tgt set in outer layers */
934 /* nt_tgt set in outer layers */
896 if (FCPARAM(isp)->isp_sccfw) {
897 nt.nt_lun = inp->in_scclun;
935 if (ISP_CAP_SCCFW(isp)) {
936 notify.nt_lun = inp->in_scclun;
898 } else {
937 } else {
899 nt.nt_lun = inp->in_lun;
938 notify.nt_lun = inp->in_lun;
900 }
939 }
901 IN_FC_MAKE_TAGID(nt.nt_tagval, 0, 0, seqid);
902 nt.nt_need_ack = 1;
903 nt.nt_lreserved = inp;
940 notify.nt_tagval = seqid;
941 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
942 notify.nt_need_ack = 1;
943 notify.nt_lreserved = inp;
904
905 if (inp->in_status != IN_MSG_RECEIVED) {
944
945 if (inp->in_status != IN_MSG_RECEIVED) {
906 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
907 inp->in_status, nt.nt_lun, loopid, inp->in_task_flags,
908 inp->in_seqid);
909 isp_notify_ack(isp, inp);
946 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
947 (void) isp_notify_ack(isp, inp);
910 return;
911 }
912
913 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) {
948 return;
949 }
950
951 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) {
914 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
915 loopid, nt.nt_lun, inp->in_seqid);
916 nt.nt_ncode = NT_ABORT_TASK_SET;
952 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", loopid, notify.nt_lun, inp->in_seqid);
953 notify.nt_ncode = NT_ABORT_TASK_SET;
917 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
954 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
918 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
919 loopid, nt.nt_lun, inp->in_seqid);
920 nt.nt_ncode = NT_CLEAR_TASK_SET;
955 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", loopid, notify.nt_lun, inp->in_seqid);
956 notify.nt_ncode = NT_CLEAR_TASK_SET;
921 } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) {
957 } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) {
922 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
923 loopid, nt.nt_lun, inp->in_seqid);
924 nt.nt_ncode = NT_LUN_RESET;
958 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", loopid, notify.nt_lun, inp->in_seqid);
959 notify.nt_ncode = NT_LUN_RESET;
925 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
960 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
926 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
927 loopid, nt.nt_lun, inp->in_seqid);
928 nt.nt_ncode = NT_TARGET_RESET;
961 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", loopid, notify.nt_lun, inp->in_seqid);
962 notify.nt_ncode = NT_TARGET_RESET;
929 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
963 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
930 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
931 loopid, nt.nt_lun, inp->in_seqid);
932 nt.nt_ncode = NT_CLEAR_ACA;
964 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", loopid, notify.nt_lun, inp->in_seqid);
965 notify.nt_ncode = NT_CLEAR_ACA;
933 } else {
966 } else {
934 isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status,
935 nt.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
936 isp_notify_ack(isp, inp);
967 isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
968 (void) isp_notify_ack(isp, inp);
937 return;
938 }
969 return;
970 }
939 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
971 isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
940}
941
972}
973
942#define HILO(x) (uint32_t) (x >> 32), (uint32_t) x
943static void
944isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
945{
974static void
975isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
976{
946 tmd_notify_t nt;
947 static const char f1[] =
948 "%s from PortID 0x%06x lun %d seq 0x%08x%08x";
949 static const char f2[] =
950 "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x%08x";
951 uint32_t sid;
977 isp_notify_t notify;
978 static const char f1[] = "%s from PortID 0x%06x lun %d seq 0x%08x";
979 static const char f2[] = "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x";
980 uint16_t chan;
981 uint32_t sid, did;
952
982
953 MEMZERO(&nt, sizeof (tmd_notify_t));
954 nt.nt_hba = isp;
955 nt.nt_iid = INI_ANY;
956 nt.nt_lun =
957 (aep->at_cmnd.fcp_cmnd_lun[0] << 8) |
958 (aep->at_cmnd.fcp_cmnd_lun[1]);
959 /*
960 * XXX: VPIDX HAS TO BE DERIVED FROM DESTINATION PORT
961 */
962 nt.nt_tagval = aep->at_rxid;
963 nt.nt_lreserved = aep;
964 sid =
965 (aep->at_hdr.s_id[0] << 16) |
966 (aep->at_hdr.s_id[1] << 8) |
967 (aep->at_hdr.s_id[2]);
983 ISP_MEMZERO(&notify, sizeof (isp_notify_t));
984 notify.nt_hba = isp;
985 notify.nt_wwn = INI_ANY;
986 notify.nt_lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | (aep->at_cmnd.fcp_cmnd_lun[1]);
987 notify.nt_tagval = aep->at_rxid;
988 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
989 notify.nt_lreserved = aep;
990 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | (aep->at_hdr.s_id[2]);
968
991
969 if (aep->at_cmnd.fcp_cmnd_task_management &
970 FCP_CMND_TMF_ABORT_TASK_SET) {
971 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
972 sid, nt.nt_lun, HILO(nt.nt_tagval));
973 nt.nt_ncode = NT_ABORT_TASK_SET;
974 } else if (aep->at_cmnd.fcp_cmnd_task_management &
975 FCP_CMND_TMF_CLEAR_TASK_SET) {
976 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
977 sid, nt.nt_lun, HILO(nt.nt_tagval));
978 nt.nt_ncode = NT_CLEAR_TASK_SET;
979 } else if (aep->at_cmnd.fcp_cmnd_task_management &
980 FCP_CMND_TMF_LUN_RESET) {
981 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
982 sid, nt.nt_lun, HILO(nt.nt_tagval));
983 nt.nt_ncode = NT_LUN_RESET;
984 } else if (aep->at_cmnd.fcp_cmnd_task_management &
985 FCP_CMND_TMF_TGT_RESET) {
986 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
987 sid, nt.nt_lun, HILO(nt.nt_tagval));
988 nt.nt_ncode = NT_TARGET_RESET;
989 nt.nt_lun = LUN_ANY;
990 } else if (aep->at_cmnd.fcp_cmnd_task_management &
991 FCP_CMND_TMF_CLEAR_ACA) {
992 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
993 sid, nt.nt_lun, HILO(nt.nt_tagval));
994 nt.nt_ncode = NT_CLEAR_ACA;
992 /* Channel has to derived from D_ID */
993 did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2];
994 for (chan = 0; chan < isp->isp_nchan; chan++) {
995 if (FCPARAM(isp, chan)->isp_portid == did) {
996 break;
997 }
998 }
999 if (chan == isp->isp_nchan) {
1000 isp_prt(isp, ISP_LOGWARN, "%s: D_ID 0x%x not found on any channel", __func__, did);
1001 /* just drop on the floor */
1002 return;
1003 }
1004 notify.nt_nphdl = NIL_HANDLE; /* unknown here */
1005 notify.nt_sid = sid;
1006 notify.nt_did = did;
1007 notify.nt_channel = chan;
1008 if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_ABORT_TASK_SET) {
1009 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", sid, notify.nt_lun, aep->at_rxid);
1010 notify.nt_ncode = NT_ABORT_TASK_SET;
1011 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_TASK_SET) {
1012 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", sid, notify.nt_lun, aep->at_rxid);
1013 notify.nt_ncode = NT_CLEAR_TASK_SET;
1014 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_LUN_RESET) {
1015 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", sid, notify.nt_lun, aep->at_rxid);
1016 notify.nt_ncode = NT_LUN_RESET;
1017 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_TGT_RESET) {
1018 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", sid, notify.nt_lun, aep->at_rxid);
1019 notify.nt_ncode = NT_TARGET_RESET;
1020 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_ACA) {
1021 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", sid, notify.nt_lun, aep->at_rxid);
1022 notify.nt_ncode = NT_CLEAR_ACA;
995 } else {
1023 } else {
996 isp_prt(isp, ISP_LOGWARN, f2,
997 aep->at_cmnd.fcp_cmnd_task_management,
998 nt.nt_lun, sid, HILO(nt.nt_tagval));
999 isp_endcmd(isp, aep, 0, 0);
1024 isp_prt(isp, ISP_LOGWARN, f2, aep->at_cmnd.fcp_cmnd_task_management, notify.nt_lun, sid, aep->at_rxid);
1025 notify.nt_ncode = NT_UNKNOWN;
1000 return;
1001 }
1026 return;
1027 }
1002 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
1028 isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
1003}
1004
1029}
1030
1005void
1031int
1006isp_notify_ack(ispsoftc_t *isp, void *arg)
1007{
1008 char storage[QENTRY_LEN];
1032isp_notify_ack(ispsoftc_t *isp, void *arg)
1033{
1034 char storage[QENTRY_LEN];
1009 uint32_t nxti, optr;
1010 void *outp;
1011
1035 void *outp;
1036
1012 if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
1013 isp_prt(isp, ISP_LOGWARN,
1014 "Request Queue Overflow For isp_notify_ack");
1015 return;
1037 /*
1038 * This is in case a Task Management Function ends up here.
1039 */
1040 if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
1041 at7_entry_t *aep = arg;
1042 return (isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0));
1016 }
1017
1043 }
1044
1018 MEMZERO(storage, QENTRY_LEN);
1045 outp = isp_getrqentry(isp);
1046 if (outp == NULL) {
1047 isp_prt(isp, ISP_LOGWARN, rqo, __func__);
1048 return (1);
1049 }
1019
1050
1020 if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
1021 at7_entry_t *aep = arg;
1022 isp_endcmd(isp, aep, 0, 0);
1023 return;
1024 } else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) {
1025 abts_rsp_t *abts_rsp = (abts_rsp_t *) storage;
1026 /*
1027 * The caller will have set response values as appropriate
1028 * in the ABTS structure just before calling us.
1029 */
1030 MEMCPY(abts_rsp, arg, QENTRY_LEN);
1031 isp_put_abts_rsp(isp, abts_rsp, (abts_rsp_t *)outp);
1032 } else if (IS_24XX(isp)) {
1051 ISP_MEMZERO(storage, QENTRY_LEN);
1052
1053 if (IS_24XX(isp)) {
1033 na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage;
1034 if (arg) {
1035 in_fcentry_24xx_t *in = arg;
1036 na->na_nphdl = in->in_nphdl;
1054 na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage;
1055 if (arg) {
1056 in_fcentry_24xx_t *in = arg;
1057 na->na_nphdl = in->in_nphdl;
1058 na->na_flags = in->in_flags & IN24XX_FLAG_PUREX_IOCB;
1037 na->na_status = in->in_status;
1038 na->na_status_subcode = in->in_status_subcode;
1039 na->na_rxid = in->in_rxid;
1040 na->na_oxid = in->in_oxid;
1059 na->na_status = in->in_status;
1060 na->na_status_subcode = in->in_status_subcode;
1061 na->na_rxid = in->in_rxid;
1062 na->na_oxid = in->in_oxid;
1063 na->na_vpidx = in->in_vpidx;
1041 if (in->in_status == IN24XX_SRR_RCVD) {
1042 na->na_srr_rxid = in->in_srr_rxid;
1043 na->na_srr_reloff_hi = in->in_srr_reloff_hi;
1044 na->na_srr_reloff_lo = in->in_srr_reloff_lo;
1045 na->na_srr_iu = in->in_srr_iu;
1046 na->na_srr_flags = 1;
1047 na->na_srr_reject_vunique = 0;
1048 na->na_srr_reject_explanation = 1;

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

1053 na->na_header.rqs_entry_count = 1;
1054 isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp);
1055 } else if (IS_FC(isp)) {
1056 na_fcentry_t *na = (na_fcentry_t *) storage;
1057 int iid = 0;
1058
1059 if (arg) {
1060 in_fcentry_t *inp = arg;
1064 if (in->in_status == IN24XX_SRR_RCVD) {
1065 na->na_srr_rxid = in->in_srr_rxid;
1066 na->na_srr_reloff_hi = in->in_srr_reloff_hi;
1067 na->na_srr_reloff_lo = in->in_srr_reloff_lo;
1068 na->na_srr_iu = in->in_srr_iu;
1069 na->na_srr_flags = 1;
1070 na->na_srr_reject_vunique = 0;
1071 na->na_srr_reject_explanation = 1;

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

1076 na->na_header.rqs_entry_count = 1;
1077 isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp);
1078 } else if (IS_FC(isp)) {
1079 na_fcentry_t *na = (na_fcentry_t *) storage;
1080 int iid = 0;
1081
1082 if (arg) {
1083 in_fcentry_t *inp = arg;
1061 MEMCPY(storage, arg, sizeof (isphdr_t));
1062 if (FCPARAM(isp)->isp_2klogin) {
1063 ((na_fcentry_e_t *)na)->na_iid =
1064 ((in_fcentry_e_t *)inp)->in_iid;
1084 ISP_MEMCPY(storage, arg, sizeof (isphdr_t));
1085 if (ISP_CAP_2KLOGIN(isp)) {
1086 ((na_fcentry_e_t *)na)->na_iid = ((in_fcentry_e_t *)inp)->in_iid;
1065 iid = ((na_fcentry_e_t *)na)->na_iid;
1066 } else {
1067 na->na_iid = inp->in_iid;
1068 iid = na->na_iid;
1069 }
1087 iid = ((na_fcentry_e_t *)na)->na_iid;
1088 } else {
1089 na->na_iid = inp->in_iid;
1090 iid = na->na_iid;
1091 }
1070 na->na_task_flags =
1071 inp->in_task_flags & TASK_FLAGS_RESERVED_MASK;
1092 na->na_task_flags = inp->in_task_flags & TASK_FLAGS_RESERVED_MASK;
1072 na->na_seqid = inp->in_seqid;
1073 na->na_flags = NAFC_RCOUNT;
1074 na->na_status = inp->in_status;
1075 if (inp->in_status == IN_RESET) {
1076 na->na_flags |= NAFC_RST_CLRD;
1077 }
1078 if (inp->in_status == IN_MSG_RECEIVED) {
1079 na->na_flags |= NAFC_TVALID;
1080 na->na_response = 0; /* XXX SUCCEEDED XXX */
1081 }
1082 } else {
1083 na->na_flags = NAFC_RST_CLRD;
1084 }
1085 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1086 na->na_header.rqs_entry_count = 1;
1093 na->na_seqid = inp->in_seqid;
1094 na->na_flags = NAFC_RCOUNT;
1095 na->na_status = inp->in_status;
1096 if (inp->in_status == IN_RESET) {
1097 na->na_flags |= NAFC_RST_CLRD;
1098 }
1099 if (inp->in_status == IN_MSG_RECEIVED) {
1100 na->na_flags |= NAFC_TVALID;
1101 na->na_response = 0; /* XXX SUCCEEDED XXX */
1102 }
1103 } else {
1104 na->na_flags = NAFC_RST_CLRD;
1105 }
1106 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1107 na->na_header.rqs_entry_count = 1;
1087 if (FCPARAM(isp)->isp_2klogin) {
1088 isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na,
1089 (na_fcentry_e_t *)outp);
1108 if (ISP_CAP_2KLOGIN(isp)) {
1109 isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na, (na_fcentry_e_t *)outp);
1090 } else {
1091 isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
1092 }
1110 } else {
1111 isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
1112 }
1093 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x "
1094 "flags %x tflags %x response %x", iid, na->na_seqid,
1113 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x flags %x tflags %x response %x", iid, na->na_seqid,
1095 na->na_flags, na->na_task_flags, na->na_response);
1096 } else {
1097 na_entry_t *na = (na_entry_t *) storage;
1098 if (arg) {
1099 in_entry_t *inp = arg;
1114 na->na_flags, na->na_task_flags, na->na_response);
1115 } else {
1116 na_entry_t *na = (na_entry_t *) storage;
1117 if (arg) {
1118 in_entry_t *inp = arg;
1100 MEMCPY(storage, arg, sizeof (isphdr_t));
1119 ISP_MEMCPY(storage, arg, sizeof (isphdr_t));
1101 na->na_iid = inp->in_iid;
1102 na->na_lun = inp->in_lun;
1103 na->na_tgt = inp->in_tgt;
1104 na->na_seqid = inp->in_seqid;
1105 if (inp->in_status == IN_RESET) {
1106 na->na_event = NA_RST_CLRD;
1107 }
1108 } else {
1109 na->na_event = NA_RST_CLRD;
1110 }
1111 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1112 na->na_header.rqs_entry_count = 1;
1113 isp_put_notify_ack(isp, na, (na_entry_t *)outp);
1120 na->na_iid = inp->in_iid;
1121 na->na_lun = inp->in_lun;
1122 na->na_tgt = inp->in_tgt;
1123 na->na_seqid = inp->in_seqid;
1124 if (inp->in_status == IN_RESET) {
1125 na->na_event = NA_RST_CLRD;
1126 }
1127 } else {
1128 na->na_event = NA_RST_CLRD;
1129 }
1130 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1131 na->na_header.rqs_entry_count = 1;
1132 isp_put_notify_ack(isp, na, (na_entry_t *)outp);
1114 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt "
1115 "%u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt,
1116 na->na_seqid, na->na_event);
1133 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt %u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt, na->na_seqid, na->na_event);
1117 }
1134 }
1118 ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
1119 ISP_ADD_REQUEST(isp, nxti);
1135 ISP_TDQE(isp, "isp_notify_ack", isp->isp_reqidx, storage);
1136 ISP_SYNC_REQUEST(isp);
1137 return (0);
1120}
1121
1138}
1139
1140int
1141isp_acknak_abts(ispsoftc_t *isp, void *arg, int errno)
1142{
1143 char storage[QENTRY_LEN];
1144 uint16_t tmpw;
1145 uint8_t tmpb;
1146 abts_t *abts = arg;
1147 abts_rsp_t *rsp = (abts_rsp_t *) storage;
1148 void *outp;
1149
1150 if (!IS_24XX(isp)) {
1151 isp_prt(isp, ISP_LOGERR, "%s: called for non-24XX card", __func__);
1152 return (0);
1153 }
1154
1155 if (abts->abts_header.rqs_entry_type != RQSTYPE_ABTS_RCVD) {
1156 isp_prt(isp, ISP_LOGERR, "%s: called for non-ABTS entry (0x%x)", __func__, abts->abts_header.rqs_entry_type);
1157 return (0);
1158 }
1159
1160 outp = isp_getrqentry(isp);
1161 if (outp == NULL) {
1162 isp_prt(isp, ISP_LOGWARN, rqo, __func__);
1163 return (1);
1164 }
1165
1166 ISP_MEMCPY(rsp, abts, QENTRY_LEN);
1167 rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP;
1168
1169 /*
1170 * Swap destination and source for response.
1171 */
1172 rsp->abts_rsp_r_ctl = BA_ACC;
1173 tmpw = rsp->abts_rsp_did_lo;
1174 tmpb = rsp->abts_rsp_did_hi;
1175 rsp->abts_rsp_did_lo = rsp->abts_rsp_sid_lo;
1176 rsp->abts_rsp_did_hi = rsp->abts_rsp_sid_hi;
1177 rsp->abts_rsp_sid_lo = tmpw;
1178 rsp->abts_rsp_sid_hi = tmpb;
1179
1180 rsp->abts_rsp_f_ctl_hi ^= 0x80; /* invert Exchange Context */
1181 rsp->abts_rsp_f_ctl_hi &= ~0x7f; /* clear Sequence Initiator and other bits */
1182 rsp->abts_rsp_f_ctl_hi |= 0x10; /* abort the whole exchange */
1183 rsp->abts_rsp_f_ctl_hi |= 0x8; /* last data frame of sequence */
1184 rsp->abts_rsp_f_ctl_hi |= 0x1; /* transfer Sequence Initiative */
1185 rsp->abts_rsp_f_ctl_lo = 0;
1186
1187 if (errno == 0) {
1188 uint16_t rx_id, ox_id;
1189
1190 rx_id = rsp->abts_rsp_rx_id;
1191 ox_id = rsp->abts_rsp_ox_id;
1192 ISP_MEMZERO(&rsp->abts_rsp_payload.ba_acc, sizeof (rsp->abts_rsp_payload.ba_acc));
1193 isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS of 0x%x being BA_ACC'd", rsp->abts_rsp_rxid_abts, rsp->abts_rsp_rxid_task);
1194 rsp->abts_rsp_payload.ba_acc.aborted_rx_id = rx_id;
1195 rsp->abts_rsp_payload.ba_acc.aborted_ox_id = ox_id;
1196 rsp->abts_rsp_payload.ba_acc.high_seq_cnt = 0xffff;
1197 } else {
1198 ISP_MEMZERO(&rsp->abts_rsp_payload.ba_rjt, sizeof (rsp->abts_rsp_payload.ba_acc));
1199 switch (errno) {
1200 case ENOMEM:
1201 rsp->abts_rsp_payload.ba_rjt.reason = 5; /* Logical Busy */
1202 break;
1203 default:
1204 rsp->abts_rsp_payload.ba_rjt.reason = 9; /* Unable to perform command request */
1205 break;
1206 }
1207 }
1208
1209 /*
1210 * The caller will have set response values as appropriate
1211 * in the ABTS structure just before calling us.
1212 */
1213 isp_put_abts_rsp(isp, rsp, (abts_rsp_t *)outp);
1214 ISP_TDQE(isp, "isp_acknak_abts", isp->isp_reqidx, storage);
1215 ISP_SYNC_REQUEST(isp);
1216 return (0);
1217}
1218
1122static void
1123isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
1124{
1125 int lun;
1126 lun = aep->at_lun;
1127 /*
1128 * The firmware status (except for the QLTM_SVALID bit) indicates
1129 * why this ATIO was sent to us.
1130 *
1131 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1132 *
1133 * If the DISCONNECTS DISABLED bit is set in the flags field,
1134 * we're still connected on the SCSI bus - i.e. the initiator
1135 * did not set DiscPriv in the identify message. We don't care
1136 * about this so it's ignored.
1137 */
1138
1219static void
1220isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
1221{
1222 int lun;
1223 lun = aep->at_lun;
1224 /*
1225 * The firmware status (except for the QLTM_SVALID bit) indicates
1226 * why this ATIO was sent to us.
1227 *
1228 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1229 *
1230 * If the DISCONNECTS DISABLED bit is set in the flags field,
1231 * we're still connected on the SCSI bus - i.e. the initiator
1232 * did not set DiscPriv in the identify message. We don't care
1233 * about this so it's ignored.
1234 */
1235
1139 switch(aep->at_status & ~QLTM_SVALID) {
1236 switch (aep->at_status & ~QLTM_SVALID) {
1140 case AT_PATH_INVALID:
1141 /*
1142 * ATIO rejected by the firmware due to disabled lun.
1143 */
1237 case AT_PATH_INVALID:
1238 /*
1239 * ATIO rejected by the firmware due to disabled lun.
1240 */
1144 isp_prt(isp, ISP_LOGERR,
1145 "rejected ATIO for disabled lun %d", lun);
1241 isp_prt(isp, ISP_LOGERR, "rejected ATIO for disabled lun %d", lun);
1146 break;
1147 case AT_NOCAP:
1148 /*
1149 * Requested Capability not available
1150 * We sent an ATIO that overflowed the firmware's
1151 * command resource count.
1152 */
1242 break;
1243 case AT_NOCAP:
1244 /*
1245 * Requested Capability not available
1246 * We sent an ATIO that overflowed the firmware's
1247 * command resource count.
1248 */
1153 isp_prt(isp, ISP_LOGERR,
1154 "rejected ATIO for lun %d because of command count"
1155 " overflow", lun);
1249 isp_prt(isp, ISP_LOGERR, "rejected ATIO for lun %d because of command count overflow", lun);
1156 break;
1157
1158 case AT_BDR_MSG:
1159 /*
1160 * If we send an ATIO to the firmware to increment
1161 * its command resource count, and the firmware is
1162 * recovering from a Bus Device Reset, it returns
1163 * the ATIO with this status. We set the command
1164 * resource count in the Enable Lun entry and do
1165 * not increment it. Therefore we should never get
1166 * this status here.
1167 */
1250 break;
1251
1252 case AT_BDR_MSG:
1253 /*
1254 * If we send an ATIO to the firmware to increment
1255 * its command resource count, and the firmware is
1256 * recovering from a Bus Device Reset, it returns
1257 * the ATIO with this status. We set the command
1258 * resource count in the Enable Lun entry and do
1259 * not increment it. Therefore we should never get
1260 * this status here.
1261 */
1168 isp_prt(isp, ISP_LOGERR, atiocope, lun,
1169 GET_BUS_VAL(aep->at_iid));
1262 isp_prt(isp, ISP_LOGERR, atiocope, lun, GET_BUS_VAL(aep->at_iid));
1170 break;
1171
1172 case AT_CDB: /* Got a CDB */
1173 case AT_PHASE_ERROR: /* Bus Phase Sequence Error */
1174 /*
1175 * Punt to platform specific layer.
1176 */
1263 break;
1264
1265 case AT_CDB: /* Got a CDB */
1266 case AT_PHASE_ERROR: /* Bus Phase Sequence Error */
1267 /*
1268 * Punt to platform specific layer.
1269 */
1177 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
1270 isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
1178 break;
1179
1180 case AT_RESET:
1181 /*
1182 * A bus reset came along and blew away this command. Why
1183 * they do this in addition the async event code stuff,
1184 * I dunno.
1185 *
1186 * Ignore it because the async event will clear things
1187 * up for us.
1188 */
1271 break;
1272
1273 case AT_RESET:
1274 /*
1275 * A bus reset came along and blew away this command. Why
1276 * they do this in addition the async event code stuff,
1277 * I dunno.
1278 *
1279 * Ignore it because the async event will clear things
1280 * up for us.
1281 */
1189 isp_prt(isp, ISP_LOGWARN, atior, lun,
1190 GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
1282 isp_prt(isp, ISP_LOGWARN, atior, lun, GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
1191 break;
1192
1193
1194 default:
1283 break;
1284
1285
1286 default:
1195 isp_prt(isp, ISP_LOGERR,
1196 "Unknown ATIO status 0x%x from loopid %d for lun %d",
1197 aep->at_status, aep->at_iid, lun);
1287 isp_prt(isp, ISP_LOGERR, "Unknown ATIO status 0x%x from loopid %d for lun %d", aep->at_status, aep->at_iid, lun);
1198 (void) isp_target_put_atio(isp, aep);
1199 break;
1200 }
1201}
1202
1203static void
1204isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1205{
1206 int lun, iid;
1207
1288 (void) isp_target_put_atio(isp, aep);
1289 break;
1290 }
1291}
1292
1293static void
1294isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1295{
1296 int lun, iid;
1297
1208 if (FCPARAM(isp)->isp_sccfw) {
1298 if (ISP_CAP_SCCFW(isp)) {
1209 lun = aep->at_scclun;
1210 } else {
1211 lun = aep->at_lun;
1212 }
1213
1299 lun = aep->at_scclun;
1300 } else {
1301 lun = aep->at_lun;
1302 }
1303
1214 if (FCPARAM(isp)->isp_2klogin) {
1304 if (ISP_CAP_2KLOGIN(isp)) {
1215 iid = ((at2e_entry_t *)aep)->at_iid;
1216 } else {
1217 iid = aep->at_iid;
1218 }
1219
1220 /*
1221 * The firmware status (except for the QLTM_SVALID bit) indicates
1222 * why this ATIO was sent to us.
1223 *
1224 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1225 *
1226 * If the DISCONNECTS DISABLED bit is set in the flags field,
1227 * we're still connected on the SCSI bus - i.e. the initiator
1228 * did not set DiscPriv in the identify message. We don't care
1229 * about this so it's ignored.
1230 */
1231
1305 iid = ((at2e_entry_t *)aep)->at_iid;
1306 } else {
1307 iid = aep->at_iid;
1308 }
1309
1310 /*
1311 * The firmware status (except for the QLTM_SVALID bit) indicates
1312 * why this ATIO was sent to us.
1313 *
1314 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1315 *
1316 * If the DISCONNECTS DISABLED bit is set in the flags field,
1317 * we're still connected on the SCSI bus - i.e. the initiator
1318 * did not set DiscPriv in the identify message. We don't care
1319 * about this so it's ignored.
1320 */
1321
1232 switch(aep->at_status & ~QLTM_SVALID) {
1322 switch (aep->at_status & ~QLTM_SVALID) {
1233 case AT_PATH_INVALID:
1234 /*
1235 * ATIO rejected by the firmware due to disabled lun.
1236 */
1323 case AT_PATH_INVALID:
1324 /*
1325 * ATIO rejected by the firmware due to disabled lun.
1326 */
1237 isp_prt(isp, ISP_LOGERR,
1238 "rejected ATIO2 for disabled lun %d", lun);
1327 isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for disabled lun %d", lun);
1239 break;
1240 case AT_NOCAP:
1241 /*
1242 * Requested Capability not available
1243 * We sent an ATIO that overflowed the firmware's
1244 * command resource count.
1245 */
1328 break;
1329 case AT_NOCAP:
1330 /*
1331 * Requested Capability not available
1332 * We sent an ATIO that overflowed the firmware's
1333 * command resource count.
1334 */
1246 isp_prt(isp, ISP_LOGERR,
1247 "rejected ATIO2 for lun %d- command count overflow", lun);
1335 isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for lun %d- command count overflow", lun);
1248 break;
1249
1250 case AT_BDR_MSG:
1251 /*
1252 * If we send an ATIO to the firmware to increment
1253 * its command resource count, and the firmware is
1254 * recovering from a Bus Device Reset, it returns
1255 * the ATIO with this status. We set the command
1256 * resource count in the Enable Lun entry and no
1257 * not increment it. Therefore we should never get
1258 * this status here.
1259 */
1260 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
1261 break;
1262
1263 case AT_CDB: /* Got a CDB */
1264 /*
1265 * Punt to platform specific layer.
1266 */
1336 break;
1337
1338 case AT_BDR_MSG:
1339 /*
1340 * If we send an ATIO to the firmware to increment
1341 * its command resource count, and the firmware is
1342 * recovering from a Bus Device Reset, it returns
1343 * the ATIO with this status. We set the command
1344 * resource count in the Enable Lun entry and no
1345 * not increment it. Therefore we should never get
1346 * this status here.
1347 */
1348 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
1349 break;
1350
1351 case AT_CDB: /* Got a CDB */
1352 /*
1353 * Punt to platform specific layer.
1354 */
1267 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
1355 isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
1268 break;
1269
1270 case AT_RESET:
1271 /*
1272 * A bus reset came along an blew away this command. Why
1273 * they do this in addition the async event code stuff,
1274 * I dunno.
1275 *
1276 * Ignore it because the async event will clear things
1277 * up for us.
1278 */
1279 isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0);
1280 break;
1281
1282
1283 default:
1356 break;
1357
1358 case AT_RESET:
1359 /*
1360 * A bus reset came along an blew away this command. Why
1361 * they do this in addition the async event code stuff,
1362 * I dunno.
1363 *
1364 * Ignore it because the async event will clear things
1365 * up for us.
1366 */
1367 isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0);
1368 break;
1369
1370
1371 default:
1284 isp_prt(isp, ISP_LOGERR,
1285 "Unknown ATIO2 status 0x%x from loopid %d for lun %d",
1286 aep->at_status, iid, lun);
1372 isp_prt(isp, ISP_LOGERR, "Unknown ATIO2 status 0x%x from loopid %d for lun %d", aep->at_status, iid, lun);
1287 (void) isp_target_put_atio(isp, aep);
1288 break;
1289 }
1290}
1291
1292static void
1293isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
1294{

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

1300 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1301 if (xs == NULL) {
1302 pl = ISP_LOGALL;
1303 }
1304 } else {
1305 xs = NULL;
1306 }
1307
1373 (void) isp_target_put_atio(isp, aep);
1374 break;
1375 }
1376}
1377
1378static void
1379isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
1380{

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

1386 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1387 if (xs == NULL) {
1388 pl = ISP_LOGALL;
1389 }
1390 } else {
1391 xs = NULL;
1392 }
1393
1308 switch(ct->ct_status & ~QLTM_SVALID) {
1394 switch (ct->ct_status & ~QLTM_SVALID) {
1309 case CT_OK:
1310 /*
1311 * There are generally 3 possibilities as to why we'd get
1312 * this condition:
1313 * We disconnected after receiving a CDB.
1314 * We sent or received data.
1315 * We sent status & command complete.
1316 */
1317
1318 if (ct->ct_flags & CT_SENDSTATUS) {
1319 break;
1320 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
1321 /*
1322 * Nothing to do in this case.
1323 */
1395 case CT_OK:
1396 /*
1397 * There are generally 3 possibilities as to why we'd get
1398 * this condition:
1399 * We disconnected after receiving a CDB.
1400 * We sent or received data.
1401 * We sent status & command complete.
1402 */
1403
1404 if (ct->ct_flags & CT_SENDSTATUS) {
1405 break;
1406 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
1407 /*
1408 * Nothing to do in this case.
1409 */
1324 isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
1325 ct->ct_iid);
1410 isp_prt(isp, pl, "CTIO- iid %d disconnected OK", ct->ct_iid);
1326 return;
1327 }
1328 break;
1329
1330 case CT_BDR_MSG:
1331 /*
1332 * Bus Device Reset message received or the SCSI Bus has
1333 * been Reset; the firmware has gone to Bus Free.

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

1346 case CT_ABORTED:
1347 /*
1348 * When an Abort message is received the firmware goes to
1349 * Bus Free and returns all outstanding CTIOs with the status
1350 * set, then sends us an Immediate Notify entry.
1351 */
1352 if (fmsg == NULL)
1353 fmsg = "ABORT TAG message sent by Initiator";
1411 return;
1412 }
1413 break;
1414
1415 case CT_BDR_MSG:
1416 /*
1417 * Bus Device Reset message received or the SCSI Bus has
1418 * been Reset; the firmware has gone to Bus Free.

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

1431 case CT_ABORTED:
1432 /*
1433 * When an Abort message is received the firmware goes to
1434 * Bus Free and returns all outstanding CTIOs with the status
1435 * set, then sends us an Immediate Notify entry.
1436 */
1437 if (fmsg == NULL)
1438 fmsg = "ABORT TAG message sent by Initiator";
1354
1355 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg);
1356 break;
1357
1358 case CT_INVAL:
1359 /*
1360 * CTIO rejected by the firmware due to disabled lun.
1361 * "Cannot Happen".
1362 */
1439 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg);
1440 break;
1441
1442 case CT_INVAL:
1443 /*
1444 * CTIO rejected by the firmware due to disabled lun.
1445 * "Cannot Happen".
1446 */
1363 isp_prt(isp, ISP_LOGERR,
1364 "Firmware rejected CTIO for disabled lun %d",
1365 ct->ct_lun);
1447 isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for disabled lun %d", ct->ct_lun);
1366 break;
1367
1368 case CT_NOPATH:
1369 /*
1370 * CTIO rejected by the firmware due "no path for the
1371 * nondisconnecting nexus specified". This means that
1372 * we tried to access the bus while a non-disconnecting
1373 * command is in process.
1374 */
1448 break;
1449
1450 case CT_NOPATH:
1451 /*
1452 * CTIO rejected by the firmware due "no path for the
1453 * nondisconnecting nexus specified". This means that
1454 * we tried to access the bus while a non-disconnecting
1455 * command is in process.
1456 */
1375 isp_prt(isp, ISP_LOGERR,
1376 "Firmware rejected CTIO for bad nexus %d/%d/%d",
1377 ct->ct_iid, ct->ct_tgt, ct->ct_lun);
1457 isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for bad nexus %d/%d/%d", ct->ct_iid, ct->ct_tgt, ct->ct_lun);
1378 break;
1379
1380 case CT_RSELTMO:
1381 fmsg = "Reselection";
1382 /*FALLTHROUGH*/
1383 case CT_TIMEOUT:
1384 if (fmsg == NULL)
1385 fmsg = "Command";
1458 break;
1459
1460 case CT_RSELTMO:
1461 fmsg = "Reselection";
1462 /*FALLTHROUGH*/
1463 case CT_TIMEOUT:
1464 if (fmsg == NULL)
1465 fmsg = "Command";
1386 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1466 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg);
1387 break;
1388
1389 case CT_PANIC:
1390 if (fmsg == NULL)
1391 fmsg = "Unrecoverable Error";
1392 /*FALLTHROUGH*/
1393 case CT_ERR:
1394 if (fmsg == NULL)

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

1403 fmsg = "terminated by TERMINATE TRANSFER";
1404 /*FALLTHROUGH*/
1405 case CT_NOACK:
1406 if (fmsg == NULL)
1407 fmsg = "unacknowledged Immediate Notify pending";
1408 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1409 break;
1410 default:
1467 break;
1468
1469 case CT_PANIC:
1470 if (fmsg == NULL)
1471 fmsg = "Unrecoverable Error";
1472 /*FALLTHROUGH*/
1473 case CT_ERR:
1474 if (fmsg == NULL)

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

1483 fmsg = "terminated by TERMINATE TRANSFER";
1484 /*FALLTHROUGH*/
1485 case CT_NOACK:
1486 if (fmsg == NULL)
1487 fmsg = "unacknowledged Immediate Notify pending";
1488 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1489 break;
1490 default:
1411 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
1412 ct->ct_status & ~QLTM_SVALID);
1491 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x", ct->ct_status & ~QLTM_SVALID);
1413 break;
1414 }
1415
1416 if (xs == NULL) {
1417 /*
1418 * There may be more than one CTIO for a data transfer,
1419 * or this may be a status CTIO we're not monitoring.
1420 *
1421 * The assumption is that they'll all be returned in the
1422 * order we got them.
1423 */
1424 if (ct->ct_syshandle == 0) {
1425 if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1492 break;
1493 }
1494
1495 if (xs == NULL) {
1496 /*
1497 * There may be more than one CTIO for a data transfer,
1498 * or this may be a status CTIO we're not monitoring.
1499 *
1500 * The assumption is that they'll all be returned in the
1501 * order we got them.
1502 */
1503 if (ct->ct_syshandle == 0) {
1504 if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1426 isp_prt(isp, pl,
1427 "intermediate CTIO completed ok");
1505 isp_prt(isp, pl, "intermediate CTIO completed ok");
1428 } else {
1506 } else {
1429 isp_prt(isp, pl,
1430 "unmonitored CTIO completed ok");
1507 isp_prt(isp, pl, "unmonitored CTIO completed ok");
1431 }
1432 } else {
1508 }
1509 } else {
1433 isp_prt(isp, pl,
1434 "NO xs for CTIO (handle 0x%x) status 0x%x",
1435 ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1510 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1436 }
1437 } else {
1438 /*
1439 * Final CTIO completed. Release DMA resources and
1440 * notify platform dependent layers.
1441 */
1442 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1443 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1444 }
1445 isp_prt(isp, pl, "final CTIO complete");
1446 /*
1447 * The platform layer will destroy the handle if appropriate.
1448 */
1511 }
1512 } else {
1513 /*
1514 * Final CTIO completed. Release DMA resources and
1515 * notify platform dependent layers.
1516 */
1517 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1518 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1519 }
1520 isp_prt(isp, pl, "final CTIO complete");
1521 /*
1522 * The platform layer will destroy the handle if appropriate.
1523 */
1449 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1524 isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1450 }
1451}
1452
1453static void
1454isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
1455{
1456 void *xs;
1457 int pl = ISP_LOGTDEBUG2;
1458 char *fmsg = NULL;
1459
1460 if (ct->ct_syshandle) {
1461 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1462 if (xs == NULL) {
1463 pl = ISP_LOGALL;
1464 }
1465 } else {
1466 xs = NULL;
1467 }
1468
1525 }
1526}
1527
1528static void
1529isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
1530{
1531 void *xs;
1532 int pl = ISP_LOGTDEBUG2;
1533 char *fmsg = NULL;
1534
1535 if (ct->ct_syshandle) {
1536 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1537 if (xs == NULL) {
1538 pl = ISP_LOGALL;
1539 }
1540 } else {
1541 xs = NULL;
1542 }
1543
1469 switch(ct->ct_status & ~QLTM_SVALID) {
1544 switch (ct->ct_status & ~QLTM_SVALID) {
1470 case CT_BUS_ERROR:
1471 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1472 /* FALL Through */
1473 case CT_DATA_OVER:
1474 case CT_DATA_UNDER:
1475 case CT_OK:
1476 /*
1477 * There are generally 2 possibilities as to why we'd get

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

1502 * When an Abort message is received the firmware goes to
1503 * Bus Free and returns all outstanding CTIOs with the status
1504 * set, then sends us an Immediate Notify entry.
1505 */
1506 if (fmsg == NULL) {
1507 fmsg = "ABORT";
1508 }
1509
1545 case CT_BUS_ERROR:
1546 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1547 /* FALL Through */
1548 case CT_DATA_OVER:
1549 case CT_DATA_UNDER:
1550 case CT_OK:
1551 /*
1552 * There are generally 2 possibilities as to why we'd get

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

1577 * When an Abort message is received the firmware goes to
1578 * Bus Free and returns all outstanding CTIOs with the status
1579 * set, then sends us an Immediate Notify entry.
1580 */
1581 if (fmsg == NULL) {
1582 fmsg = "ABORT";
1583 }
1584
1510 isp_prt(isp, ISP_LOGTDEBUG0,
1511 "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
1585 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
1512 break;
1513
1514 case CT_INVAL:
1515 /*
1516 * CTIO rejected by the firmware - invalid data direction.
1517 */
1518 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction");
1519 break;
1520
1521 case CT_RSELTMO:
1522 fmsg = "failure to reconnect to initiator";
1523 /*FALLTHROUGH*/
1524 case CT_TIMEOUT:
1525 if (fmsg == NULL)
1526 fmsg = "command";
1586 break;
1587
1588 case CT_INVAL:
1589 /*
1590 * CTIO rejected by the firmware - invalid data direction.
1591 */
1592 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction");
1593 break;
1594
1595 case CT_RSELTMO:
1596 fmsg = "failure to reconnect to initiator";
1597 /*FALLTHROUGH*/
1598 case CT_TIMEOUT:
1599 if (fmsg == NULL)
1600 fmsg = "command";
1527 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1601 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg);
1528 break;
1529
1530 case CT_ERR:
1531 fmsg = "Completed with Error";
1532 /*FALLTHROUGH*/
1533 case CT_LOGOUT:
1534 if (fmsg == NULL)
1535 fmsg = "Port Logout";

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

1548 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
1549 break;
1550
1551 case CT_INVRXID:
1552 /*
1553 * CTIO rejected by the firmware because an invalid RX_ID.
1554 * Just print a message.
1555 */
1602 break;
1603
1604 case CT_ERR:
1605 fmsg = "Completed with Error";
1606 /*FALLTHROUGH*/
1607 case CT_LOGOUT:
1608 if (fmsg == NULL)
1609 fmsg = "Port Logout";

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

1622 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
1623 break;
1624
1625 case CT_INVRXID:
1626 /*
1627 * CTIO rejected by the firmware because an invalid RX_ID.
1628 * Just print a message.
1629 */
1556 isp_prt(isp, ISP_LOGWARN,
1557 "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1630 isp_prt(isp, ISP_LOGWARN, "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1558 break;
1559
1560 default:
1631 break;
1632
1633 default:
1561 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
1562 ct->ct_status & ~QLTM_SVALID);
1634 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", ct->ct_status & ~QLTM_SVALID);
1563 break;
1564 }
1565
1566 if (xs == NULL) {
1567 /*
1568 * There may be more than one CTIO for a data transfer,
1569 * or this may be a status CTIO we're not monitoring.
1570 *
1571 * The assumption is that they'll all be returned in the
1572 * order we got them.
1573 */
1574 if (ct->ct_syshandle == 0) {
1575 if ((ct->ct_flags & CT2_SENDSTATUS) == 0) {
1635 break;
1636 }
1637
1638 if (xs == NULL) {
1639 /*
1640 * There may be more than one CTIO for a data transfer,
1641 * or this may be a status CTIO we're not monitoring.
1642 *
1643 * The assumption is that they'll all be returned in the
1644 * order we got them.
1645 */
1646 if (ct->ct_syshandle == 0) {
1647 if ((ct->ct_flags & CT2_SENDSTATUS) == 0) {
1576 isp_prt(isp, pl,
1577 "intermediate CTIO completed ok");
1648 isp_prt(isp, pl, "intermediate CTIO completed ok");
1578 } else {
1649 } else {
1579 isp_prt(isp, pl,
1580 "unmonitored CTIO completed ok");
1650 isp_prt(isp, pl, "unmonitored CTIO completed ok");
1581 }
1582 } else {
1651 }
1652 } else {
1583 isp_prt(isp, pl,
1584 "NO xs for CTIO (handle 0x%x) status 0x%x",
1585 ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1653 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1586 }
1587 } else {
1588 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1589 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1590 }
1591 if (ct->ct_flags & CT2_SENDSTATUS) {
1592 /*
1593 * Sent status and command complete.

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

1600 isp_prt(isp, pl, "status CTIO complete");
1601 } else {
1602 /*
1603 * Final CTIO completed. Release DMA resources and
1604 * notify platform dependent layers.
1605 */
1606 isp_prt(isp, pl, "data CTIO complete");
1607 }
1654 }
1655 } else {
1656 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1657 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1658 }
1659 if (ct->ct_flags & CT2_SENDSTATUS) {
1660 /*
1661 * Sent status and command complete.

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

1668 isp_prt(isp, pl, "status CTIO complete");
1669 } else {
1670 /*
1671 * Final CTIO completed. Release DMA resources and
1672 * notify platform dependent layers.
1673 */
1674 isp_prt(isp, pl, "data CTIO complete");
1675 }
1608 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1676 isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1609 /*
1610 * The platform layer will destroy the handle if appropriate.
1611 */
1612 }
1613}
1614
1615static void
1616isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)

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

1623 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1624 if (xs == NULL) {
1625 pl = ISP_LOGALL;
1626 }
1627 } else {
1628 xs = NULL;
1629 }
1630
1677 /*
1678 * The platform layer will destroy the handle if appropriate.
1679 */
1680 }
1681}
1682
1683static void
1684isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)

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

1691 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1692 if (xs == NULL) {
1693 pl = ISP_LOGALL;
1694 }
1695 } else {
1696 xs = NULL;
1697 }
1698
1631 switch(ct->ct_nphdl) {
1699 switch (ct->ct_nphdl) {
1632 case CT7_BUS_ERROR:
1633 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1634 /* FALL Through */
1635 case CT7_DATA_OVER:
1636 case CT7_DATA_UNDER:
1637 case CT7_OK:
1638 /*
1639 * There are generally 2 possibilities as to why we'd get

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

1653 /*
1654 * When an Abort message is received the firmware goes to
1655 * Bus Free and returns all outstanding CTIOs with the status
1656 * set, then sends us an Immediate Notify entry.
1657 */
1658 if (fmsg == NULL) {
1659 fmsg = "ABORT";
1660 }
1700 case CT7_BUS_ERROR:
1701 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1702 /* FALL Through */
1703 case CT7_DATA_OVER:
1704 case CT7_DATA_UNDER:
1705 case CT7_OK:
1706 /*
1707 * There are generally 2 possibilities as to why we'd get

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

1721 /*
1722 * When an Abort message is received the firmware goes to
1723 * Bus Free and returns all outstanding CTIOs with the status
1724 * set, then sends us an Immediate Notify entry.
1725 */
1726 if (fmsg == NULL) {
1727 fmsg = "ABORT";
1728 }
1661 isp_prt(isp, ISP_LOGTDEBUG0,
1662 "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
1729 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
1663 break;
1664
1665 case CT7_TIMEOUT:
1666 if (fmsg == NULL) {
1667 fmsg = "command";
1668 }
1730 break;
1731
1732 case CT7_TIMEOUT:
1733 if (fmsg == NULL) {
1734 fmsg = "command";
1735 }
1669 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1736 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg);
1670 break;
1671
1672 case CT7_ERR:
1673 fmsg = "Completed with Error";
1674 /*FALLTHROUGH*/
1675 case CT7_LOGOUT:
1676 if (fmsg == NULL) {
1677 fmsg = "Port Logout";

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

1689 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
1690 break;
1691
1692 case CT7_INVRXID:
1693 /*
1694 * CTIO rejected by the firmware because an invalid RX_ID.
1695 * Just print a message.
1696 */
1737 break;
1738
1739 case CT7_ERR:
1740 fmsg = "Completed with Error";
1741 /*FALLTHROUGH*/
1742 case CT7_LOGOUT:
1743 if (fmsg == NULL) {
1744 fmsg = "Port Logout";

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

1756 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
1757 break;
1758
1759 case CT7_INVRXID:
1760 /*
1761 * CTIO rejected by the firmware because an invalid RX_ID.
1762 * Just print a message.
1763 */
1697 isp_prt(isp, ISP_LOGWARN,
1698 "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1764 isp_prt(isp, ISP_LOGWARN, "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1699 break;
1700
1701 case CT7_REASSY_ERR:
1702 isp_prt(isp, ISP_LOGWARN, "reassembly error");
1703 break;
1704
1705 case CT7_SRR:
1706 isp_prt(isp, ISP_LOGWARN, "SRR received");
1707 break;
1708
1709 default:
1765 break;
1766
1767 case CT7_REASSY_ERR:
1768 isp_prt(isp, ISP_LOGWARN, "reassembly error");
1769 break;
1770
1771 case CT7_SRR:
1772 isp_prt(isp, ISP_LOGWARN, "SRR received");
1773 break;
1774
1775 default:
1710 isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x",
1711 ct->ct_nphdl);
1776 isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x", ct->ct_nphdl);
1712 break;
1713 }
1714
1715 if (xs == NULL) {
1716 /*
1717 * There may be more than one CTIO for a data transfer,
1718 * or this may be a status CTIO we're not monitoring.
1719 *
1720 * The assumption is that they'll all be returned in the
1721 * order we got them.
1722 */
1723 if (ct->ct_syshandle == 0) {
1724 if (ct->ct_flags & CT7_TERMINATE) {
1777 break;
1778 }
1779
1780 if (xs == NULL) {
1781 /*
1782 * There may be more than one CTIO for a data transfer,
1783 * or this may be a status CTIO we're not monitoring.
1784 *
1785 * The assumption is that they'll all be returned in the
1786 * order we got them.
1787 */
1788 if (ct->ct_syshandle == 0) {
1789 if (ct->ct_flags & CT7_TERMINATE) {
1725 isp_prt(isp, ISP_LOGINFO,
1726 "termination of 0x%x complete",
1727 ct->ct_rxid);
1790 isp_prt(isp, ISP_LOGINFO, "termination of 0x%x complete", ct->ct_rxid);
1728 } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) {
1791 } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) {
1729 isp_prt(isp, pl,
1730 "intermediate CTIO completed ok");
1792 isp_prt(isp, pl, "intermediate CTIO completed ok");
1731 } else {
1793 } else {
1732 isp_prt(isp, pl,
1733 "unmonitored CTIO completed ok");
1794 isp_prt(isp, pl, "unmonitored CTIO completed ok");
1734 }
1735 } else {
1795 }
1796 } else {
1736 isp_prt(isp, pl,
1737 "NO xs for CTIO (handle 0x%x) status 0x%x",
1738 ct->ct_syshandle, ct->ct_nphdl);
1797 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_nphdl);
1739 }
1740 } else {
1798 }
1799 } else {
1741 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1800 if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) {
1742 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1743 }
1801 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1802 }
1744 if (ct->ct_flags & CT2_SENDSTATUS) {
1803 if (ct->ct_flags & CT7_SENDSTATUS) {
1745 /*
1746 * Sent status and command complete.
1747 *
1748 * We're now really done with this command, so we
1749 * punt to the platform dependent layers because
1750 * only there can we do the appropriate command
1751 * complete thread synchronization.
1752 */
1753 isp_prt(isp, pl, "status CTIO complete");
1754 } else {
1755 /*
1756 * Final CTIO completed. Release DMA resources and
1757 * notify platform dependent layers.
1758 */
1759 isp_prt(isp, pl, "data CTIO complete");
1760 }
1804 /*
1805 * Sent status and command complete.
1806 *
1807 * We're now really done with this command, so we
1808 * punt to the platform dependent layers because
1809 * only there can we do the appropriate command
1810 * complete thread synchronization.
1811 */
1812 isp_prt(isp, pl, "status CTIO complete");
1813 } else {
1814 /*
1815 * Final CTIO completed. Release DMA resources and
1816 * notify platform dependent layers.
1817 */
1818 isp_prt(isp, pl, "data CTIO complete");
1819 }
1761 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1820 isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1762 /*
1763 * The platform layer will destroy the handle if appropriate.
1764 */
1765 }
1766}
1821 /*
1822 * The platform layer will destroy the handle if appropriate.
1823 */
1824 }
1825}
1826
1827static void
1828isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx)
1829{
1830 uint8_t ochan, chan, lochan, hichan;
1831
1832 /*
1833 * Check to see whether we got a wildcard channel.
1834 * If so, we have to iterate over all channels.
1835 */
1836 ochan = chan = ISP_GET_VPIDX(isp, inot_24xx->in_vpidx);
1837 if (chan == 0xff) {
1838 lochan = 0;
1839 hichan = isp->isp_nchan;
1840 } else {
1841 if (chan >= isp->isp_nchan) {
1842 char buf[64];
1843 ISP_SNPRINTF(buf, sizeof buf, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status);
1844 isp_print_bytes(isp, buf, QENTRY_LEN, inot_24xx);
1845 (void) isp_notify_ack(isp, inot_24xx);
1846 return;
1847 }
1848 lochan = chan;
1849 hichan = chan + 1;
1850 }
1851 isp_prt(isp, ISP_LOGTDEBUG1, "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x", __func__, lochan, hichan-1, inot_24xx->in_status, inot_24xx->in_rxid);
1852 for (chan = lochan; chan < hichan; chan++) {
1853 switch (inot_24xx->in_status) {
1854 case IN24XX_LIP_RESET:
1855 case IN24XX_LINK_RESET:
1856 case IN24XX_PORT_LOGOUT:
1857 case IN24XX_PORT_CHANGED:
1858 case IN24XX_LINK_FAILED:
1859 case IN24XX_SRR_RCVD:
1860 case IN24XX_ELS_RCVD:
1861 inot_24xx->in_vpidx = chan;
1862 isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx);
1863 break;
1864 default:
1865 isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d", __func__, inot_24xx->in_status, chan);
1866 (void) isp_notify_ack(isp, inot_24xx);
1867 break;
1868 }
1869 }
1870 inot_24xx->in_vpidx = ochan;
1871}
1767#endif
1872#endif