Merge from vendor branch OPENSSH:
[dragonfly.git] / sys / dev / disk / isp / isp_target.c
1 /* $FreeBSD: src/sys/dev/isp/isp_target.c,v 1.5.4.10 2002/07/29 04:25:59 mjacob Exp $ */
2 /* $DragonFly: src/sys/dev/disk/isp/isp_target.c,v 1.4 2004/02/13 01:04:15 joerg Exp $ */
3 /*
4  * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
5  *
6  * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
7  * All rights reserved.
8  * mjacob@feral.com
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice immediately at the beginning of the file, without modification,
15  *    this list of conditions, and the following disclaimer.
16  * 2. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 /*
33  * Bug fixes gratefully acknowledged from:
34  *      Oded Kedem <oded@kashya.com>
35  */
36 /*
37  * Include header file appropriate for platform we're building on.
38  */
39
40 #ifdef  __NetBSD__
41 #include <dev/ic/isp_netbsd.h>
42 #endif
43 #if defined(__DragonFly__) || defined(__FreeBSD__)
44 #include "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
54 static const char atiocope[] =
55     "ATIO returned for lun %d because it was in the middle of Bus Device Reset "
56     "on bus %d";
57 static const char atior[] =
58     "ATIO returned on for lun %d on from IID %d because a Bus Reset occurred "
59     "on bus %d";
60
61 static void isp_got_msg(struct ispsoftc *, int, in_entry_t *);
62 static void isp_got_msg_fc(struct ispsoftc *, int, in_fcentry_t *);
63 static void isp_notify_ack(struct ispsoftc *, void *);
64 static void isp_handle_atio(struct ispsoftc *, at_entry_t *);
65 static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *);
66 static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *);
67 static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *);
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,
76  * SCSI Command processing, and Immediate Notification events.
77  *
78  * You start by writing a request queue entry to enable target mode (and
79  * establish some resource limitations which you can modify later).
80  * The f/w responds with a LUN ENABLE or LUN MODIFY response with
81  * the status of this action. If the enable was successful, you can expect...
82  *
83  * Response queue entries with SCSI commands encapsulate show up in an ATIO
84  * (Accept Target IO) type- sometimes with enough info to stop the command at
85  * this level. Ultimately the driver has to feed back to the f/w's request
86  * queue a sequence of CTIOs (continue target I/O) that describe data to
87  * be moved and/or status to be sent) and finally finishing with sending
88  * to the f/w's response queue an ATIO which then completes the handshake
89  * with the f/w for that command. There's a lot of variations on this theme,
90  * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel
91  * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic
92  * gist of it.
93  *
94  * The third group that can show up in the response queue are Immediate
95  * Notification events. These include things like notifications of SCSI bus
96  * resets, or Bus Device Reset messages or other messages received. This
97  * a classic oddbins area. It can get  a little weird because you then turn
98  * around and acknowledge the Immediate Notify by writing an entry onto the
99  * request queue and then the f/w turns around and gives you an acknowledgement
100  * to *your* acknowledgement on the response queue (the idea being to let
101  * the f/w tell you when the event is *really* over I guess).
102  *
103  */
104
105
106 /*
107  * A new response queue entry has arrived. The interrupt service code
108  * has already swizzled it into the platform dependent from canonical form.
109  *
110  * Because of the way this driver is designed, unfortunately most of the
111  * actual synchronization work has to be done in the platform specific
112  * code- we have no synchroniation primitives in the common code.
113  */
114
115 int
116 isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
117 {
118         u_int16_t status, seqid;
119         union {
120                 at_entry_t      *atiop;
121                 at2_entry_t     *at2iop;
122                 ct_entry_t      *ctiop;
123                 ct2_entry_t     *ct2iop;
124                 lun_entry_t     *lunenp;
125                 in_entry_t      *inotp;
126                 in_fcentry_t    *inot_fcp;
127                 na_entry_t      *nackp;
128                 na_fcentry_t    *nack_fcp;
129                 isphdr_t        *hp;
130                 void *          *vp;
131 #define atiop           unp.atiop
132 #define at2iop          unp.at2iop
133 #define ctiop           unp.ctiop
134 #define ct2iop          unp.ct2iop
135 #define lunenp          unp.lunenp
136 #define inotp           unp.inotp
137 #define inot_fcp        unp.inot_fcp
138 #define nackp           unp.nackp
139 #define nack_fcp        unp.nack_fcp
140 #define hdrp            unp.hp
141         } unp;
142         u_int8_t local[QENTRY_LEN];
143         int bus, type, rval = 1;
144
145         type = isp_get_response_type(isp, (isphdr_t *)vptr);
146         unp.vp = vptr;
147
148         ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
149
150         switch(type) {
151         case RQSTYPE_ATIO:
152                 isp_get_atio(isp, atiop, (at_entry_t *) local);
153                 isp_handle_atio(isp, (at_entry_t *) local);
154                 break;
155         case RQSTYPE_CTIO:
156                 isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
157                 isp_handle_ctio(isp, (ct_entry_t *) local);
158                 break;
159         case RQSTYPE_ATIO2:
160                 isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
161                 isp_handle_atio2(isp, (at2_entry_t *) local);
162                 break;
163         case RQSTYPE_CTIO2:
164                 isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
165                 isp_handle_ctio2(isp, (ct2_entry_t *) local);
166                 break;
167         case RQSTYPE_ENABLE_LUN:
168         case RQSTYPE_MODIFY_LUN:
169                 isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
170                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
171                 break;
172
173         case RQSTYPE_NOTIFY:
174                 /*
175                  * Either the ISP received a SCSI message it can't
176                  * handle, or it's returning an Immed. Notify entry
177                  * we sent. We can send Immed. Notify entries to
178                  * increment the firmware's resource count for them
179                  * (we set this initially in the Enable Lun entry).
180                  */
181                 bus = 0;
182                 if (IS_FC(isp)) {
183                         isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local);
184                         inot_fcp = (in_fcentry_t *) local;
185                         status = inot_fcp->in_status;
186                         seqid = inot_fcp->in_seqid;
187                 } else {
188                         isp_get_notify(isp, inotp, (in_entry_t *)local);
189                         inotp = (in_entry_t *) local;
190                         status = inotp->in_status & 0xff;
191                         seqid = inotp->in_seqid;
192                         if (IS_DUALBUS(isp)) {
193                                 bus = GET_BUS_VAL(inotp->in_iid);
194                                 SET_BUS_VAL(inotp->in_iid, 0);
195                         }
196                 }
197                 isp_prt(isp, ISP_LOGTDEBUG0,
198                     "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
199                     bus, status, seqid);
200
201                 /*
202                  * ACK it right away.
203                  */
204                 isp_notify_ack(isp, (status == IN_RESET)? NULL : local);
205                 switch (status) {
206                 case IN_RESET:
207                         (void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
208                         break;
209                 case IN_MSG_RECEIVED:
210                 case IN_IDE_RECEIVED:
211                         if (IS_FC(isp)) {
212                                 isp_got_msg_fc(isp, bus, (in_fcentry_t *)local);
213                         } else {
214                                 isp_got_msg(isp, bus, (in_entry_t *)local);
215                         }
216                         break;
217                 case IN_RSRC_UNAVAIL:
218                         isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
219                         break;
220                 case IN_PORT_LOGOUT:
221                 case IN_ABORT_TASK:
222                 case IN_PORT_CHANGED:
223                 case IN_GLOBAL_LOGO:
224                         (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
225                         break;
226                 default:
227                         isp_prt(isp, ISP_LOGERR,
228                             "bad status (0x%x) in isp_target_notify", status);
229                         break;
230                 }
231                 break;
232
233         case RQSTYPE_NOTIFY_ACK:
234                 /*
235                  * The ISP is acknowledging our acknowledgement of an
236                  * Immediate Notify entry for some asynchronous event.
237                  */
238                 if (IS_FC(isp)) {
239                         isp_get_notify_ack_fc(isp, nack_fcp,
240                             (na_fcentry_t *)local);
241                         nack_fcp = (na_fcentry_t *)local;
242                         isp_prt(isp, ISP_LOGTDEBUG1,
243                             "Notify Ack status=0x%x seqid 0x%x",
244                             nack_fcp->na_status, nack_fcp->na_seqid);
245                 } else {
246                         isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
247                         nackp = (na_entry_t *)local;
248                         isp_prt(isp, ISP_LOGTDEBUG1,
249                             "Notify Ack event 0x%x status=0x%x seqid 0x%x",
250                             nackp->na_event, nackp->na_status, nackp->na_seqid);
251                 }
252                 break;
253         default:
254                 isp_prt(isp, ISP_LOGERR,
255                     "Unknown entry type 0x%x in isp_target_notify", type);
256                 rval = 0;
257                 break;
258         }
259 #undef  atiop
260 #undef  at2iop
261 #undef  ctiop
262 #undef  ct2iop
263 #undef  lunenp
264 #undef  inotp
265 #undef  inot_fcp
266 #undef  nackp
267 #undef  nack_fcp
268 #undef  hdrp
269         return (rval);
270 }
271
272  
273 /*
274  * Toggle (on/off) target mode for bus/target/lun
275  *
276  * The caller has checked for overlap and legality.
277  *
278  * Note that not all of bus, target or lun can be paid attention to.
279  * Note also that this action will not be complete until the f/w writes
280  * response entry. The caller is responsible for synchronizing this.
281  */
282 int
283 isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
284     int cmd_cnt, int inot_cnt, u_int32_t opaque)
285 {
286         lun_entry_t el;
287         u_int16_t nxti, optr;
288         void *outp;
289
290
291         MEMZERO(&el, sizeof (el));
292         if (IS_DUALBUS(isp)) {
293                 el.le_rsvd = (bus & 0x1) << 7;
294         }
295         el.le_cmd_count = cmd_cnt;
296         el.le_in_count = inot_cnt;
297         if (cmd == RQSTYPE_ENABLE_LUN) {
298                 if (IS_SCSI(isp)) {
299                         el.le_flags = LUN_TQAE|LUN_DISAD;
300                         el.le_cdb6len = 12;
301                         el.le_cdb7len = 12;
302                 }
303         } else if (cmd == -RQSTYPE_ENABLE_LUN) {
304                 cmd = RQSTYPE_ENABLE_LUN;
305                 el.le_cmd_count = 0;
306                 el.le_in_count = 0;
307         } else if (cmd == -RQSTYPE_MODIFY_LUN) {
308                 cmd = RQSTYPE_MODIFY_LUN;
309                 el.le_ops = LUN_CCDECR | LUN_INDECR;
310         } else {
311                 el.le_ops = LUN_CCINCR | LUN_ININCR;
312         }
313         el.le_header.rqs_entry_type = cmd;
314         el.le_header.rqs_entry_count = 1;
315         el.le_reserved = opaque;
316         if (IS_SCSI(isp)) {
317                 el.le_tgt = tgt;
318                 el.le_lun = lun;
319         } else if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
320                 el.le_lun = lun;
321         }
322         el.le_timeout = 2;
323
324         if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
325                 isp_prt(isp, ISP_LOGERR,
326                     "Request Queue Overflow in isp_lun_cmd");
327                 return (-1);
328         }
329         ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
330         isp_put_enable_lun(isp, &el, outp);
331         ISP_ADD_REQUEST(isp, nxti);
332         return (0);
333 }
334
335
336 int
337 isp_target_put_entry(struct ispsoftc *isp, void *ap)
338 {
339         void *outp;
340         u_int16_t nxti, optr;
341         u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
342
343         if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
344                 isp_prt(isp, ISP_LOGWARN,
345                     "Request Queue Overflow in isp_target_put_entry");
346                 return (-1);
347         }
348         switch (etype) {
349         case RQSTYPE_ATIO:
350                 isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
351                 break;
352         case RQSTYPE_ATIO2:
353                 isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
354                 break;
355         case RQSTYPE_CTIO:
356                 isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
357                 break;
358         case RQSTYPE_CTIO2:
359                 isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
360                 break;
361         default:
362                 isp_prt(isp, ISP_LOGERR,
363                     "Unknown type 0x%x in isp_put_entry", etype);
364                 return (-1);
365         }
366
367         ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);;
368         ISP_ADD_REQUEST(isp, nxti);
369         return (0);
370 }
371
372 int
373 isp_target_put_atio(struct ispsoftc *isp, void *arg)
374 {
375         union {
376                 at_entry_t _atio;
377                 at2_entry_t _atio2;
378         } atun;
379
380         MEMZERO(&atun, sizeof atun);
381         if (IS_FC(isp)) {
382                 at2_entry_t *aep = arg;
383                 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
384                 atun._atio2.at_header.rqs_entry_count = 1;
385                 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
386                         atun._atio2.at_scclun = (u_int16_t) aep->at_scclun;
387                 } else {
388                         atun._atio2.at_lun = (u_int8_t) aep->at_lun;
389                 }
390                 atun._atio2.at_status = CT_OK;
391         } else {
392                 at_entry_t *aep = arg;
393                 atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO;
394                 atun._atio.at_header.rqs_entry_count = 1;
395                 atun._atio.at_handle = aep->at_handle;
396                 atun._atio.at_iid = aep->at_iid;
397                 atun._atio.at_tgt = aep->at_tgt;
398                 atun._atio.at_lun = aep->at_lun;
399                 atun._atio.at_tag_type = aep->at_tag_type;
400                 atun._atio.at_tag_val = aep->at_tag_val;
401                 atun._atio.at_status = (aep->at_flags & AT_TQAE);
402                 atun._atio.at_status |= CT_OK;
403         }
404         return (isp_target_put_entry(isp, &atun));
405 }
406
407 /*
408  * Command completion- both for handling cases of no resources or
409  * no blackhole driver, or other cases where we have to, inline,
410  * finish the command sanely, or for normal command completion.
411  *
412  * The 'completion' code value has the scsi status byte in the low 8 bits.
413  * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have
414  * the sense key and  bits 16..23 have the ASCQ and bits 24..31 have the ASC
415  * values.
416  *
417  * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't
418  * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
419  *
420  * For both parallel && fibre channel, we use the feature that does
421  * an automatic resource autoreplenish so we don't have then later do
422  * put of an atio to replenish the f/w's resource count.
423  */
424
425 int
426 isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
427 {
428         int sts;
429         union {
430                 ct_entry_t _ctio;
431                 ct2_entry_t _ctio2;
432         } un;
433
434         MEMZERO(&un, sizeof un);
435         sts = code & 0xff;
436
437         if (IS_FC(isp)) {
438                 at2_entry_t *aep = arg;
439                 ct2_entry_t *cto = &un._ctio2;
440
441                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
442                 cto->ct_header.rqs_entry_count = 1;
443                 cto->ct_iid = aep->at_iid;
444                 if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
445                         cto->ct_lun = aep->at_lun;
446                 }
447                 cto->ct_rxid = aep->at_rxid;
448                 cto->rsp.m1.ct_scsi_status = sts & 0xff;
449                 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
450                 if (hdl == 0) {
451                         cto->ct_flags |= CT2_CCINCR;
452                 }
453                 if (aep->at_datalen) {
454                         cto->ct_resid = aep->at_datalen;
455                         cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
456                 }
457                 if ((sts & 0xff) == SCSI_CHECK && (sts & ECMD_SVALID)) {
458                         cto->rsp.m1.ct_resp[0] = 0xf0;
459                         cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
460                         cto->rsp.m1.ct_resp[7] = 8;
461                         cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
462                         cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
463                         cto->rsp.m1.ct_senselen = 16;
464                         cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
465                 }
466                 cto->ct_syshandle = hdl;
467         } else {
468                 at_entry_t *aep = arg;
469                 ct_entry_t *cto = &un._ctio;
470
471                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
472                 cto->ct_header.rqs_entry_count = 1;
473                 cto->ct_fwhandle = aep->at_handle;
474                 cto->ct_iid = aep->at_iid;
475                 cto->ct_tgt = aep->at_tgt;
476                 cto->ct_lun = aep->at_lun;
477                 cto->ct_tag_type = aep->at_tag_type;
478                 cto->ct_tag_val = aep->at_tag_val;
479                 if (aep->at_flags & AT_TQAE) {
480                         cto->ct_flags |= CT_TQAE;
481                 }
482                 cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA;
483                 if (hdl == 0) {
484                         cto->ct_flags |= CT_CCINCR;
485                 }
486                 cto->ct_scsi_status = sts;
487                 cto->ct_syshandle = hdl;
488         }
489         return (isp_target_put_entry(isp, &un));
490 }
491
492 int
493 isp_target_async(struct ispsoftc *isp, int bus, int event)
494 {
495         tmd_event_t evt;
496         tmd_msg_t msg;
497
498         switch (event) {
499         /*
500          * These three we handle here to propagate an effective bus reset
501          * upstream, but these do not require any immediate notify actions
502          * so we return when done.
503          */
504         case ASYNC_LIP_F8:
505         case ASYNC_LIP_OCCURRED:
506         case ASYNC_LOOP_UP:
507         case ASYNC_LOOP_DOWN:
508         case ASYNC_LOOP_RESET:
509         case ASYNC_PTPMODE:
510                 /*
511                  * These don't require any immediate notify actions. We used
512                  * treat them like SCSI Bus Resets, but that was just plain
513                  * wrong. Let the normal CTIO completion report what occurred.
514                  */
515                 return (0);
516
517         case ASYNC_BUS_RESET:
518         case ASYNC_TIMEOUT_RESET:
519                 if (IS_FC(isp)) {
520                         return (0); /* we'll be getting an inotify instead */
521                 }
522                 evt.ev_bus = bus;
523                 evt.ev_event = event;
524                 (void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
525                 break;
526         case ASYNC_DEVICE_RESET:
527                 /*
528                  * Bus Device Reset resets a specific target, so
529                  * we pass this as a synthesized message.
530                  */
531                 MEMZERO(&msg, sizeof msg);
532                 if (IS_FC(isp)) {
533                         msg.nt_iid = FCPARAM(isp)->isp_loopid;
534                 } else {
535                         msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
536                 }
537                 msg.nt_bus = bus;
538                 msg.nt_msg[0] = MSG_BUS_DEV_RESET;
539                 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
540                 break;
541         default:
542                 isp_prt(isp, ISP_LOGERR,
543                     "isp_target_async: unknown event 0x%x", event);
544                 break;
545         }
546         if (isp->isp_state == ISP_RUNSTATE)
547                 isp_notify_ack(isp, NULL);
548         return(0);
549 }
550
551
552 /*
553  * Process a received message.
554  * The ISP firmware can handle most messages, there are only
555  * a few that we need to deal with:
556  * - abort: clean up the current command
557  * - abort tag and clear queue
558  */
559
560 static void
561 isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp)
562 {
563         u_int8_t status = inp->in_status & ~QLTM_SVALID;
564
565         if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
566                 tmd_msg_t msg;
567
568                 MEMZERO(&msg, sizeof (msg));
569                 msg.nt_bus = bus;
570                 msg.nt_iid = inp->in_iid;
571                 msg.nt_tgt = inp->in_tgt;
572                 msg.nt_lun = inp->in_lun;
573                 msg.nt_tagtype = inp->in_tag_type;
574                 msg.nt_tagval = inp->in_tag_val;
575                 MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
576                 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
577         } else {
578                 isp_prt(isp, ISP_LOGERR,
579                     "unknown immediate notify status 0x%x", inp->in_status);
580         }
581 }
582
583 /*
584  * Synthesize a message from the task management flags in a FCP_CMND_IU.
585  */
586 static void
587 isp_got_msg_fc(struct ispsoftc *isp, int bus, in_fcentry_t *inp)
588 {
589         int lun;
590         static const char f1[] = "%s from iid %d lun %d seq 0x%x";
591         static const char f2[] = 
592             "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
593
594         if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
595                 lun = inp->in_scclun;
596         } else {
597                 lun = inp->in_lun;
598         }
599
600         if (inp->in_status != IN_MSG_RECEIVED) {
601                 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
602                     inp->in_status, lun, inp->in_iid,
603                     inp->in_task_flags,  inp->in_seqid);
604         } else {
605                 tmd_msg_t msg;
606
607                 MEMZERO(&msg, sizeof (msg));
608                 msg.nt_bus = bus;
609                 msg.nt_iid = inp->in_iid;
610                 msg.nt_tagval = inp->in_seqid;
611                 msg.nt_lun = lun;
612
613                 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) {
614                         isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK",
615                             inp->in_iid, msg.nt_lun, inp->in_seqid);
616                         msg.nt_msg[0] = MSG_ABORT_TAG;
617                 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
618                         isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
619                             inp->in_iid, msg.nt_lun, inp->in_seqid);
620                         msg.nt_msg[0] = MSG_CLEAR_QUEUE;
621                 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
622                         isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
623                             inp->in_iid, msg.nt_lun, inp->in_seqid);
624                         msg.nt_msg[0] = MSG_BUS_DEV_RESET;
625                 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
626                         isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
627                             inp->in_iid, msg.nt_lun, inp->in_seqid);
628                         /* ???? */
629                         msg.nt_msg[0] = MSG_REL_RECOVERY;
630                 } else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) {
631                         isp_prt(isp, ISP_LOGINFO, f1, "TERMINATE TASK",
632                             inp->in_iid, msg.nt_lun, inp->in_seqid);
633                         msg.nt_msg[0] = MSG_TERM_IO_PROC;
634                 } else {
635                         isp_prt(isp, ISP_LOGWARN, f2, "task flag",
636                             inp->in_status, msg.nt_lun, inp->in_iid,
637                             inp->in_task_flags,  inp->in_seqid);
638                 }
639                 if (msg.nt_msg[0]) {
640                         (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
641                 }
642         }
643 }
644
645 static void
646 isp_notify_ack(struct ispsoftc *isp, void *arg)
647 {
648         char storage[QENTRY_LEN];
649         u_int16_t nxti, optr;
650         void *outp;
651
652         if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
653                 isp_prt(isp, ISP_LOGWARN,
654                     "Request Queue Overflow For isp_notify_ack");
655                 return;
656         }
657
658         MEMZERO(storage, QENTRY_LEN);
659
660         if (IS_FC(isp)) {
661                 na_fcentry_t *na = (na_fcentry_t *) storage;
662                 if (arg) {
663                         in_fcentry_t *inp = arg;
664                         MEMCPY(storage, arg, sizeof (isphdr_t));
665                         na->na_iid = inp->in_iid;
666                         if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
667                                 na->na_lun = inp->in_scclun;
668                         } else {
669                                 na->na_lun = inp->in_lun;
670                         }
671                         na->na_task_flags = inp->in_task_flags;
672                         na->na_seqid = inp->in_seqid;
673                         na->na_flags = NAFC_RCOUNT;
674                         na->na_status = inp->in_status;
675                         if (inp->in_status == IN_RESET) {
676                                 na->na_flags |= NAFC_RST_CLRD;
677                         }
678                 } else {
679                         na->na_flags = NAFC_RST_CLRD;
680                 }
681                 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
682                 na->na_header.rqs_entry_count = 1;
683                 isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
684         } else {
685                 na_entry_t *na = (na_entry_t *) storage;
686                 if (arg) {
687                         in_entry_t *inp = arg;
688                         MEMCPY(storage, arg, sizeof (isphdr_t));
689                         na->na_iid = inp->in_iid;
690                         na->na_lun = inp->in_lun;
691                         na->na_tgt = inp->in_tgt;
692                         na->na_seqid = inp->in_seqid;
693                         if (inp->in_status == IN_RESET) {
694                                 na->na_event = NA_RST_CLRD;
695                         }
696                 } else {
697                         na->na_event = NA_RST_CLRD;
698                 }
699                 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
700                 na->na_header.rqs_entry_count = 1;
701                 isp_put_notify_ack(isp, na, (na_entry_t *)outp);
702         }
703         ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
704         ISP_ADD_REQUEST(isp, nxti);
705 }
706
707 static void
708 isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
709 {
710         int lun;
711         lun = aep->at_lun;
712         /*
713          * The firmware status (except for the QLTM_SVALID bit) indicates
714          * why this ATIO was sent to us.
715          *
716          * If QLTM_SVALID is set, the firware has recommended Sense Data.
717          *
718          * If the DISCONNECTS DISABLED bit is set in the flags field,
719          * we're still connected on the SCSI bus - i.e. the initiator
720          * did not set DiscPriv in the identify message. We don't care
721          * about this so it's ignored.
722          */
723
724         switch(aep->at_status & ~QLTM_SVALID) {
725         case AT_PATH_INVALID:
726                 /*
727                  * ATIO rejected by the firmware due to disabled lun.
728                  */
729                 isp_prt(isp, ISP_LOGERR,
730                     "rejected ATIO for disabled lun %d", lun);
731                 break;
732         case AT_NOCAP:
733                 /*
734                  * Requested Capability not available
735                  * We sent an ATIO that overflowed the firmware's
736                  * command resource count.
737                  */
738                 isp_prt(isp, ISP_LOGERR,
739                     "rejected ATIO for lun %d because of command count"
740                     " overflow", lun);
741                 break;
742
743         case AT_BDR_MSG:
744                 /*
745                  * If we send an ATIO to the firmware to increment
746                  * its command resource count, and the firmware is
747                  * recovering from a Bus Device Reset, it returns
748                  * the ATIO with this status. We set the command
749                  * resource count in the Enable Lun entry and do
750                  * not increment it. Therefore we should never get
751                  * this status here.
752                  */
753                 isp_prt(isp, ISP_LOGERR, atiocope, lun,
754                     GET_BUS_VAL(aep->at_iid));
755                 break;
756
757         case AT_CDB:            /* Got a CDB */
758         case AT_PHASE_ERROR:    /* Bus Phase Sequence Error */
759                 /*
760                  * Punt to platform specific layer.
761                  */
762                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
763                 break;
764
765         case AT_RESET:
766                 /*
767                  * A bus reset came along an blew away this command. Why
768                  * they do this in addition the async event code stuff,
769                  * I dunno.
770                  *
771                  * Ignore it because the async event will clear things
772                  * up for us.
773                  */
774                 isp_prt(isp, ISP_LOGWARN, atior, lun,
775                     GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
776                 break;
777
778
779         default:
780                 isp_prt(isp, ISP_LOGERR,
781                     "Unknown ATIO status 0x%x from initiator %d for lun %d",
782                     aep->at_status, aep->at_iid, lun);
783                 (void) isp_target_put_atio(isp, aep);
784                 break;
785         }
786 }
787
788 static void
789 isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
790 {
791         int lun;
792
793         if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
794                 lun = aep->at_scclun;
795         } else {
796                 lun = aep->at_lun;
797         }
798
799         /*
800          * The firmware status (except for the QLTM_SVALID bit) indicates
801          * why this ATIO was sent to us.
802          *
803          * If QLTM_SVALID is set, the firware has recommended Sense Data.
804          *
805          * If the DISCONNECTS DISABLED bit is set in the flags field,
806          * we're still connected on the SCSI bus - i.e. the initiator
807          * did not set DiscPriv in the identify message. We don't care
808          * about this so it's ignored.
809          */
810
811         switch(aep->at_status & ~QLTM_SVALID) {
812         case AT_PATH_INVALID:
813                 /*
814                  * ATIO rejected by the firmware due to disabled lun.
815                  */
816                 isp_prt(isp, ISP_LOGERR,
817                     "rejected ATIO2 for disabled lun %d", lun);
818                 break;
819         case AT_NOCAP:
820                 /*
821                  * Requested Capability not available
822                  * We sent an ATIO that overflowed the firmware's
823                  * command resource count.
824                  */
825                 isp_prt(isp, ISP_LOGERR,
826                     "rejected ATIO2 for lun %d- command count overflow", lun);
827                 break;
828
829         case AT_BDR_MSG:
830                 /*
831                  * If we send an ATIO to the firmware to increment
832                  * its command resource count, and the firmware is
833                  * recovering from a Bus Device Reset, it returns
834                  * the ATIO with this status. We set the command
835                  * resource count in the Enable Lun entry and no
836                  * not increment it. Therefore we should never get
837                  * this status here.
838                  */
839                 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
840                 break;
841
842         case AT_CDB:            /* Got a CDB */
843                 /*
844                  * Punt to platform specific layer.
845                  */
846                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
847                 break;
848
849         case AT_RESET:
850                 /*
851                  * A bus reset came along an blew away this command. Why
852                  * they do this in addition the async event code stuff,
853                  * I dunno.
854                  *
855                  * Ignore it because the async event will clear things
856                  * up for us.
857                  */
858                 isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid, 0);
859                 break;
860
861
862         default:
863                 isp_prt(isp, ISP_LOGERR,
864                     "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
865                     aep->at_status, aep->at_iid, lun);
866                 (void) isp_target_put_atio(isp, aep);
867                 break;
868         }
869 }
870
871 static void
872 isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
873 {
874         void *xs;
875         int pl = ISP_LOGTDEBUG2;
876         char *fmsg = NULL;
877
878         if (ct->ct_syshandle) {
879                 xs = isp_find_xs(isp, ct->ct_syshandle);
880                 if (xs == NULL)
881                         pl = ISP_LOGALL;
882         } else {
883                 xs = NULL;
884         }
885
886         switch(ct->ct_status & ~QLTM_SVALID) {
887         case CT_OK:
888                 /*
889                  * There are generally 3 possibilities as to why we'd get
890                  * this condition:
891                  *      We disconnected after receiving a CDB.
892                  *      We sent or received data.
893                  *      We sent status & command complete.
894                  */
895
896                 if (ct->ct_flags & CT_SENDSTATUS) {
897                         break;
898                 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
899                         /*
900                          * Nothing to do in this case.
901                          */
902                         isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
903                             ct->ct_iid);
904                         return;
905                 }
906                 break;
907
908         case CT_BDR_MSG:
909                 /*
910                  * Bus Device Reset message received or the SCSI Bus has
911                  * been Reset; the firmware has gone to Bus Free.
912                  *
913                  * The firmware generates an async mailbox interupt to
914                  * notify us of this and returns outstanding CTIOs with this
915                  * status. These CTIOs are handled in that same way as
916                  * CT_ABORTED ones, so just fall through here.
917                  */
918                 fmsg = "Bus Device Reset";
919                 /*FALLTHROUGH*/
920         case CT_RESET:
921                 if (fmsg == NULL)
922                         fmsg = "Bus Reset";
923                 /*FALLTHROUGH*/
924         case CT_ABORTED:
925                 /*
926                  * When an Abort message is received the firmware goes to
927                  * Bus Free and returns all outstanding CTIOs with the status
928                  * set, then sends us an Immediate Notify entry.
929                  */
930                 if (fmsg == NULL)
931                         fmsg = "ABORT TAG message sent by Initiator";
932
933                 isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
934                 break;
935
936         case CT_INVAL:
937                 /*
938                  * CTIO rejected by the firmware due to disabled lun.
939                  * "Cannot Happen".
940                  */
941                 isp_prt(isp, ISP_LOGERR,
942                     "Firmware rejected CTIO for disabled lun %d",
943                     ct->ct_lun);
944                 break;
945
946         case CT_NOPATH:
947                 /*
948                  * CTIO rejected by the firmware due "no path for the
949                  * nondisconnecting nexus specified". This means that
950                  * we tried to access the bus while a non-disconnecting
951                  * command is in process.
952                  */
953                 isp_prt(isp, ISP_LOGERR,
954                     "Firmware rejected CTIO for bad nexus %d/%d/%d",
955                     ct->ct_iid, ct->ct_tgt, ct->ct_lun);
956                 break;
957
958         case CT_RSELTMO:
959                 fmsg = "Reselection";
960                 /*FALLTHROUGH*/
961         case CT_TIMEOUT:
962                 if (fmsg == NULL)
963                         fmsg = "Command";
964                 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
965                 break;
966
967         case    CT_PANIC:
968                 if (fmsg == NULL)
969                         fmsg = "Unrecoverable Error";
970                 /*FALLTHROUGH*/
971         case CT_ERR:
972                 if (fmsg == NULL)
973                         fmsg = "Completed with Error";
974                 /*FALLTHROUGH*/
975         case CT_PHASE_ERROR:
976                 if (fmsg == NULL)
977                         fmsg = "Phase Sequence Error";
978                 /*FALLTHROUGH*/
979         case CT_TERMINATED:
980                 if (fmsg == NULL)
981                         fmsg = "terminated by TERMINATE TRANSFER";
982                 /*FALLTHROUGH*/
983         case CT_NOACK:
984                 if (fmsg == NULL)
985                         fmsg = "unacknowledged Immediate Notify pending";
986                 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
987                 break;
988         default:
989                 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
990                     ct->ct_status & ~QLTM_SVALID);
991                 break;
992         }
993
994         if (xs == NULL) {
995                 /*
996                  * There may be more than one CTIO for a data transfer,
997                  * or this may be a status CTIO we're not monitoring.
998                  *
999                  * The assumption is that they'll all be returned in the
1000                  * order we got them.
1001                  */
1002                 if (ct->ct_syshandle == 0) {
1003                         if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1004                                 isp_prt(isp, pl,
1005                                     "intermediate CTIO completed ok");
1006                         } else {
1007                                 isp_prt(isp, pl,
1008                                     "unmonitored CTIO completed ok");
1009                         }
1010                 } else {
1011                         isp_prt(isp, pl,
1012                             "NO xs for CTIO (handle 0x%x) status 0x%x",
1013                             ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1014                 }
1015         } else {
1016                 /*
1017                  * Final CTIO completed. Release DMA resources and
1018                  * notify platform dependent layers.
1019                  */
1020                 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1021                         ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1022                 }
1023                 isp_prt(isp, pl, "final CTIO complete");
1024                 /*
1025                  * The platform layer will destroy the handle if appropriate.
1026                  */
1027                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1028         }
1029 }
1030
1031 static void
1032 isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
1033 {
1034         XS_T *xs;
1035         int pl = ISP_LOGTDEBUG2;
1036         char *fmsg = NULL;
1037
1038         if (ct->ct_syshandle) {
1039                 xs = isp_find_xs(isp, ct->ct_syshandle);
1040                 if (xs == NULL)
1041                         pl = ISP_LOGALL;
1042         } else {
1043                 xs = NULL;
1044         }
1045
1046         switch(ct->ct_status & ~QLTM_SVALID) {
1047         case CT_BUS_ERROR:
1048                 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1049                 /* FALL Through */
1050         case CT_DATA_OVER:
1051         case CT_DATA_UNDER:
1052         case CT_OK:
1053                 /*
1054                  * There are generally 2 possibilities as to why we'd get
1055                  * this condition:
1056                  *      We sent or received data.
1057                  *      We sent status & command complete.
1058                  */
1059
1060                 break;
1061
1062         case CT_BDR_MSG:
1063                 /*
1064                  * Target Reset function received.
1065                  *
1066                  * The firmware generates an async mailbox interupt to
1067                  * notify us of this and returns outstanding CTIOs with this
1068                  * status. These CTIOs are handled in that same way as
1069                  * CT_ABORTED ones, so just fall through here.
1070                  */
1071                 fmsg = "TARGET RESET Task Management Function Received";
1072                 /*FALLTHROUGH*/
1073         case CT_RESET:
1074                 if (fmsg == NULL)
1075                         fmsg = "LIP Reset";
1076                 /*FALLTHROUGH*/
1077         case CT_ABORTED:
1078                 /*
1079                  * When an Abort message is received the firmware goes to
1080                  * Bus Free and returns all outstanding CTIOs with the status
1081                  * set, then sends us an Immediate Notify entry.
1082                  */
1083                 if (fmsg == NULL)
1084                         fmsg = "ABORT Task Management Function Received";
1085
1086                 isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
1087                 break;
1088
1089         case CT_INVAL:
1090                 /*
1091                  * CTIO rejected by the firmware - invalid data direction.
1092                  */
1093                 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data directiond");
1094                 break;
1095
1096         case CT_RSELTMO:
1097                 fmsg = "failure to reconnect to initiator";
1098                 /*FALLTHROUGH*/
1099         case CT_TIMEOUT:
1100                 if (fmsg == NULL)
1101                         fmsg = "command";
1102                 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1103                 break;
1104
1105         case CT_ERR:
1106                 fmsg = "Completed with Error";
1107                 /*FALLTHROUGH*/
1108         case CT_LOGOUT:
1109                 if (fmsg == NULL)
1110                         fmsg = "Port Logout";
1111                 /*FALLTHROUGH*/
1112         case CT_PORTNOTAVAIL:
1113                 if (fmsg == NULL)
1114                         fmsg = "Port not available";
1115         case CT_PORTCHANGED:
1116                 if (fmsg == NULL)
1117                         fmsg = "Port Changed";
1118         case CT_NOACK:
1119                 if (fmsg == NULL)
1120                         fmsg = "unacknowledged Immediate Notify pending";
1121                 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1122                 break;
1123
1124         case CT_INVRXID:
1125                 /*
1126                  * CTIO rejected by the firmware because an invalid RX_ID.
1127                  * Just print a message.
1128                  */
1129                 isp_prt(isp, ISP_LOGERR,
1130                     "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1131                 break;
1132
1133         default:
1134                 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
1135                     ct->ct_status & ~QLTM_SVALID);
1136                 break;
1137         }
1138
1139         if (xs == NULL) {
1140                 /*
1141                  * There may be more than one CTIO for a data transfer,
1142                  * or this may be a status CTIO we're not monitoring.
1143                  *
1144                  * The assumption is that they'll all be returned in the
1145                  * order we got them.
1146                  */
1147                 if (ct->ct_syshandle == 0) {
1148                         if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1149                                 isp_prt(isp, pl,
1150                                     "intermediate CTIO completed ok");
1151                         } else {
1152                                 isp_prt(isp, pl,
1153                                     "unmonitored CTIO completed ok");
1154                         }
1155                 } else {
1156                         isp_prt(isp, pl,
1157                             "NO xs for CTIO (handle 0x%x) status 0x%x",
1158                             ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1159                 }
1160         } else {
1161                 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1162                         ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1163                 }
1164                 if (ct->ct_flags & CT_SENDSTATUS) {
1165                         /*
1166                          * Sent status and command complete.
1167                          *
1168                          * We're now really done with this command, so we
1169                          * punt to the platform dependent layers because
1170                          * only there can we do the appropriate command
1171                          * complete thread synchronization.
1172                          */
1173                         isp_prt(isp, pl, "status CTIO complete");
1174                 } else {
1175                         /*
1176                          * Final CTIO completed. Release DMA resources and
1177                          * notify platform dependent layers.
1178                          */
1179                         isp_prt(isp, pl, "data CTIO complete");
1180                 }
1181                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1182                 /*
1183                  * The platform layer will destroy the handle if appropriate.
1184                  */
1185         }
1186 }
1187 #endif