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